/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class Main { static Object exactCheck = new ExactCheck(); static Object abstractCheckImpl = new AbstractCheckImpl(); static Object interfaceCheckImpl = new InterfaceCheckImpl(); static Object normalCheck = new NormalCheck(); static Object regularObject = new Object(); static Object objectArray = new Object[2]; static Object intArray = new int[2]; static Object doubleArray = new double[2]; static Object exactArray = new ExactCheck[2]; static Object normalArray = new NormalCheck[2]; static Object field; public static void main(String[] args) { checkInstanceOfNonTryCatch(); // We also check for a method with try/catch because the compiler then makes a slow // path unconditionally save its live registers. checkInstanceOfTryCatch(); checkCheckCast(); } public static void checkInstanceOfNonTryCatch() { check(true, exactCheck instanceof ExactCheck); check(false, regularObject instanceof ExactCheck); check(true, abstractCheckImpl instanceof AbstractCheck); check(false, regularObject instanceof AbstractCheck); check(true, interfaceCheckImpl instanceof InterfaceCheck); check(false, regularObject instanceof InterfaceCheck); check(true, normalCheck instanceof NormalCheck); check(true, exactCheck instanceof NormalCheck); check(false, regularObject instanceof NormalCheck); check(false, regularObject instanceof int[]); check(false, objectArray instanceof int[]); check(true, intArray instanceof int[]); check(false, doubleArray instanceof int[]); check(false, regularObject instanceof ExactCheck[]); check(false, objectArray instanceof ExactCheck[]); check(false, doubleArray instanceof ExactCheck[]); check(true, exactArray instanceof ExactCheck[]); check(false, normalArray instanceof ExactCheck[]); check(false, regularObject instanceof NormalCheck[]); check(false, objectArray instanceof NormalCheck[]); check(false, doubleArray instanceof NormalCheck[]); check(true, exactArray instanceof NormalCheck[]); check(true, normalArray instanceof NormalCheck[]); check(false, regularObject instanceof Object[]); check(true, objectArray instanceof Object[]); check(false, doubleArray instanceof Object[]); check(true, exactArray instanceof Object[]); check(true, normalArray instanceof Object[]); } public static void checkInstanceOfTryCatch() { try { check(true, exactCheck instanceof ExactCheck); check(false, regularObject instanceof ExactCheck); check(true, abstractCheckImpl instanceof AbstractCheck); check(false, regularObject instanceof AbstractCheck); check(true, interfaceCheckImpl instanceof InterfaceCheck); check(false, regularObject instanceof InterfaceCheck); check(true, normalCheck instanceof NormalCheck); check(true, exactCheck instanceof NormalCheck); check(false, regularObject instanceof NormalCheck); check(false, regularObject instanceof int[]); check(false, objectArray instanceof int[]); check(true, intArray instanceof int[]); check(false, doubleArray instanceof int[]); check(false, regularObject instanceof ExactCheck[]); check(false, objectArray instanceof ExactCheck[]); check(false, doubleArray instanceof ExactCheck[]); check(true, exactArray instanceof ExactCheck[]); check(false, normalArray instanceof ExactCheck[]); check(false, regularObject instanceof NormalCheck[]); check(false, objectArray instanceof NormalCheck[]); check(false, doubleArray instanceof NormalCheck[]); check(true, exactArray instanceof NormalCheck[]); check(true, normalArray instanceof NormalCheck[]); check(false, regularObject instanceof Object[]); check(true, objectArray instanceof Object[]); check(false, doubleArray instanceof Object[]); check(true, exactArray instanceof Object[]); check(true, normalArray instanceof Object[]); } catch (Throwable t) { throw new Error("Unreachable"); } } public static void check(boolean expected, boolean actual) { if (actual != expected) { throw new Error("Expected " + expected + ", got " + actual); } } public static void checkCheckCast() { // Exact check. field = (ExactCheck)exactCheck; try { field = (ExactCheck)regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Abstract check. field = (AbstractCheck)abstractCheckImpl; try { field = (AbstractCheck)regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Interface check. field = (InterfaceCheck)interfaceCheckImpl; try { field = (InterfaceCheck)regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Normal check. field = (NormalCheck)normalCheck; field = (NormalCheck)exactCheck; try { field = (NormalCheck)regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Primitive array check. try { field = (int[])regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} try { field = (int[])objectArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} field = (int[])intArray; try { field = (int[])doubleArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Array with final component type check. try { field = (ExactCheck[])regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} try { field = (ExactCheck[])objectArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} try { field = (ExactCheck[])doubleArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} field = (ExactCheck[])exactArray; try { field = (ExactCheck[])normalArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} // Array with non final component type check. try { field = (NormalCheck[])regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} try { field = (NormalCheck[])objectArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} try { field = (NormalCheck[])doubleArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} field = (NormalCheck[])exactArray; field = (NormalCheck[])normalArray; // Object[] check. try{ field = (Object[])regularObject; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} field = (Object[])objectArray; try { field = (Object[])doubleArray; throw new Error("Can't reach here"); } catch (ClassCastException ignore) {} field = (Object[])exactArray; field = (Object[])normalArray; } } class NormalCheck { } final class ExactCheck extends NormalCheck { } abstract class AbstractCheck { } class AbstractCheckImpl extends AbstractCheck { } interface InterfaceCheck { } class InterfaceCheckImpl implements InterfaceCheck { }