xref: /aosp_15_r20/art/test/594-invoke-super/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException;
18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker //
21*795d594fSAndroid Build Coastguard Worker // Two classes A and B with method foo().
22*795d594fSAndroid Build Coastguard Worker //
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker class A {
A()25*795d594fSAndroid Build Coastguard Worker   A() { System.out.println("new A"); }
26*795d594fSAndroid Build Coastguard Worker 
foo()27*795d594fSAndroid Build Coastguard Worker   public void foo() { System.out.println("I am A's foo"); }
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker   // We previously used to invoke this method with a Y instance, due
30*795d594fSAndroid Build Coastguard Worker   // to invoke-super underspecified behavior.
bar()31*795d594fSAndroid Build Coastguard Worker   public void bar() { System.out.println("I am A's bar"); }
32*795d594fSAndroid Build Coastguard Worker }
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker class B {
B()35*795d594fSAndroid Build Coastguard Worker   B() { System.out.println("new B"); }
36*795d594fSAndroid Build Coastguard Worker 
foo()37*795d594fSAndroid Build Coastguard Worker   public void foo() { System.out.println("I am B's foo"); }
38*795d594fSAndroid Build Coastguard Worker }
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker //
41*795d594fSAndroid Build Coastguard Worker // Two subclasses X and Y that call foo() on super.
42*795d594fSAndroid Build Coastguard Worker //
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker class X extends A {
foo()45*795d594fSAndroid Build Coastguard Worker   public void foo() { super.foo(); }
46*795d594fSAndroid Build Coastguard Worker }
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker class Y extends B {
foo()49*795d594fSAndroid Build Coastguard Worker   public void foo() { super.foo(); }
50*795d594fSAndroid Build Coastguard Worker }
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker //
53*795d594fSAndroid Build Coastguard Worker // Driver class.
54*795d594fSAndroid Build Coastguard Worker //
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker public class Main {
57*795d594fSAndroid Build Coastguard Worker 
main(String[] args)58*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Exception {
59*795d594fSAndroid Build Coastguard Worker     // The normal stuff, X's super goes to A, Y's super goes to B.
60*795d594fSAndroid Build Coastguard Worker     new X().foo();
61*795d594fSAndroid Build Coastguard Worker     new Y().foo();
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker     // And now it gets interesting.
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker     // In bytecode, we define a class Z that is a subclass of A, and we call
66*795d594fSAndroid Build Coastguard Worker     // invoke-super on an instance of Y.
67*795d594fSAndroid Build Coastguard Worker     Class<?> z = Class.forName("Z");
68*795d594fSAndroid Build Coastguard Worker     Method m = z.getMethod("foo");
69*795d594fSAndroid Build Coastguard Worker     try {
70*795d594fSAndroid Build Coastguard Worker       m.invoke(z.newInstance());
71*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected InvocationTargetException");
72*795d594fSAndroid Build Coastguard Worker     } catch (InvocationTargetException e) {
73*795d594fSAndroid Build Coastguard Worker       if (!(e.getCause() instanceof NoSuchMethodError)) {
74*795d594fSAndroid Build Coastguard Worker         throw new Error("Expected NoSuchMethodError");
75*795d594fSAndroid Build Coastguard Worker       }
76*795d594fSAndroid Build Coastguard Worker     }
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker     System.out.println("passed");
79*795d594fSAndroid Build Coastguard Worker   }
80*795d594fSAndroid Build Coastguard Worker }
81