1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.lang.reflect.*;
18 import java.util.*;
19 
20 class Main {
21   private static boolean z = true;
22   private static byte b = 8;
23   private static char c = '\u2714';
24   private static double d = Math.PI;
25   private static float f = 3.14f;
26   private static int i = 32;
27   private static long j = 0x0123456789abcdefL;
28   private static short s = 16;
29 
testFieldReflection()30   public static void testFieldReflection() throws Exception {
31     Field f;
32 
33     f = Main.class.getDeclaredField("z");
34     System.out.println(f.getBoolean(null));
35     f = Main.class.getDeclaredField("b");
36     System.out.println(f.getByte(null));
37     f = Main.class.getDeclaredField("c");
38     System.out.println(f.getChar(null));
39     f = Main.class.getDeclaredField("d");
40     System.out.println(f.getDouble(null));
41     f = Main.class.getDeclaredField("f");
42     System.out.println(f.getFloat(null));
43     f = Main.class.getDeclaredField("i");
44     System.out.println(f.getInt(null));
45     f = Main.class.getDeclaredField("j");
46     System.out.println(f.getLong(null));
47     f = Main.class.getDeclaredField("s");
48     System.out.println(f.getShort(null));
49 
50     f = Main.class.getDeclaredField("z");
51     f.setBoolean(null, false);
52     f = Main.class.getDeclaredField("b");
53     f.setByte(null, (byte) 7);
54     f = Main.class.getDeclaredField("c");
55     f.setChar(null, 'y');
56     f = Main.class.getDeclaredField("d");
57     f.setDouble(null, 2.7);
58     f = Main.class.getDeclaredField("f");
59     f.setFloat(null, 2.7f);
60     f = Main.class.getDeclaredField("i");
61     f.setInt(null, 31);
62     f = Main.class.getDeclaredField("j");
63     f.setLong(null, 63);
64     f = Main.class.getDeclaredField("s");
65     f.setShort(null, (short) 15);
66 
67     f = Main.class.getDeclaredField("z");
68     System.out.println(f.getBoolean(null));
69     f = Main.class.getDeclaredField("b");
70     System.out.println(f.getByte(null));
71     f = Main.class.getDeclaredField("c");
72     System.out.println(f.getChar(null));
73     f = Main.class.getDeclaredField("d");
74     System.out.println(f.getDouble(null));
75     f = Main.class.getDeclaredField("f");
76     System.out.println(f.getFloat(null));
77     f = Main.class.getDeclaredField("i");
78     System.out.println(f.getInt(null));
79     f = Main.class.getDeclaredField("j");
80     System.out.println(f.getLong(null));
81     f = Main.class.getDeclaredField("s");
82     System.out.println(f.getShort(null));
83 
84     f = Main.class.getDeclaredField("z");
85     f.set(null, Boolean.valueOf(true));
86     f = Main.class.getDeclaredField("b");
87     f.set(null, Byte.valueOf((byte) 6));
88     f = Main.class.getDeclaredField("c");
89     f.set(null, Character.valueOf('z'));
90     f = Main.class.getDeclaredField("d");
91     f.set(null, Double.valueOf(1.3));
92     f = Main.class.getDeclaredField("f");
93     f.set(null, Float.valueOf(1.3f));
94     f = Main.class.getDeclaredField("i");
95     f.set(null, Integer.valueOf(30));
96     f = Main.class.getDeclaredField("j");
97     f.set(null, Long.valueOf(62));
98     f.set(null, Integer.valueOf(62));
99     f = Main.class.getDeclaredField("s");
100     f.set(null, Short.valueOf((short) 14));
101 
102     f = Main.class.getDeclaredField("z");
103     System.out.println(f.getBoolean(null));
104     f = Main.class.getDeclaredField("b");
105     System.out.println(f.getByte(null));
106     f = Main.class.getDeclaredField("c");
107     System.out.println(f.getChar(null));
108     f = Main.class.getDeclaredField("d");
109     System.out.println(f.getDouble(null));
110     f = Main.class.getDeclaredField("f");
111     System.out.println(f.getFloat(null));
112     f = Main.class.getDeclaredField("i");
113     System.out.println(f.getInt(null));
114     f = Main.class.getDeclaredField("j");
115     System.out.println(f.getLong(null));
116     f = Main.class.getDeclaredField("s");
117     System.out.println(f.getShort(null));
118 
119     try {
120       f = Main.class.getDeclaredField("s");
121       f.set(null, Integer.valueOf(14));
122       System.out.println("************* should have thrown!");
123     } catch (IllegalArgumentException expected) {
124       System.out.println("got expected IllegalArgumentException");
125     }
126 
127     f = Main.class.getDeclaredField("z");
128     show(f.get(null));
129     f = Main.class.getDeclaredField("b");
130     show(f.get(null));
131     f = Main.class.getDeclaredField("c");
132     show(f.get(null));
133     f = Main.class.getDeclaredField("d");
134     show(f.get(null));
135     f = Main.class.getDeclaredField("f");
136     show(f.get(null));
137     f = Main.class.getDeclaredField("i");
138     show(f.get(null));
139     f = Main.class.getDeclaredField("j");
140     show(f.get(null));
141     f = Main.class.getDeclaredField("s");
142     show(f.get(null));
143 
144     /*
145     private static boolean z = true;
146     private static byte b = 8;
147     private static char c = '\u2714';
148     private static double d = Math.PI;
149     private static float f = 3.14f;
150     private static int i = 32;
151     private static long j = 0x0123456789abcdefL;
152     private static short s = 16;
153     */
154   }
155 
show(Object o)156   private static void show(Object o) {
157     System.out.println(o + " (" + (o != null ? o.getClass() : "null") + ")");
158   }
159 
160   /**
161    * Sorts the input array using the comparator and returns the sorted array.
162    */
sort(Object[] objects, Comparator<Object> comp)163   private static Object[] sort(Object[] objects, Comparator<Object> comp) {
164     Arrays.sort(objects, comp);
165     return objects;
166   }
167 
testMethodReflection()168   public static void testMethodReflection() throws Exception {
169     Comparator<Object> comp = new Comparator<Object>() {
170       public int compare(Object a, Object b) {
171         return a.toString().compareTo(b.toString());
172       }
173       public boolean equals(Object b) {
174         return this == b;
175       }
176     };
177 
178     // Sort the return values by their string values since the order is undefined by the spec.
179     System.out.println(Arrays.toString(sort(String.class.getDeclaredConstructors(), comp)));
180     System.out.println(Arrays.toString(sort(String.class.getDeclaredFields(), comp)));
181     System.out.println(Arrays.toString(sort(String.class.getDeclaredMethods(), comp)));
182 
183     System.out.println(Arrays.toString(Main.class.getInterfaces()));
184     System.out.println(Arrays.toString(String.class.getInterfaces()));
185 
186     System.out.println(Main.class.getModifiers());
187     System.out.println(String.class.getModifiers());
188 
189     System.out.println(String.class.isAssignableFrom(Object.class));
190     System.out.println(Object.class.isAssignableFrom(String.class));
191 
192     System.out.println(String.class.isInstance("hello"));
193     System.out.println(String.class.isInstance(123));
194 
195     Method m;
196 
197     m = Main.class.getDeclaredMethod("IV", int.class);
198     System.out.println(Arrays.toString(m.getParameterTypes()));
199     show(m.invoke(null, 4444));
200     System.out.println(Arrays.toString(m.getParameterTypes()));
201 
202     m = Main.class.getDeclaredMethod("IIV", int.class, int.class);
203     System.out.println(Arrays.toString(m.getParameterTypes()));
204     show(m.invoke(null, 1111, 2222));
205 
206     m = Main.class.getDeclaredMethod("III", int.class, int.class);
207     System.out.println(Arrays.toString(m.getParameterTypes()));
208     show(m.invoke(null, 1111, 2222));
209 
210     m = Main.class.getDeclaredMethod("sumArray", int[].class);
211     System.out.println(Arrays.toString(m.getParameterTypes()));
212     show(m.invoke(null, new int[] { 1, 2, 3, 4 }));
213 
214     m = Main.class.getDeclaredMethod("concat", String[].class);
215     System.out.println(Arrays.toString(m.getParameterTypes()));
216     show(m.invoke(null, (Object) new String[] { "h", "e", "l", "l", "o" }));
217 
218     m = Main.class.getDeclaredMethod("ZBCDFIJSV", boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class);
219     System.out.println(Arrays.toString(m.getParameterTypes()));
220     show(m.invoke(null, true, (byte) 0, '1', 2, 3, 4, 5, (short) 6));
221 
222     m = Main.class.getDeclaredMethod("ZBCDLFIJSV", boolean.class, byte.class, char.class, double.class, String.class, float.class, int.class, long.class, short.class);
223     System.out.println(Arrays.toString(m.getParameterTypes()));
224     show(m.invoke(null, true, (byte) 0, '1', 2, "hello world", 3, 4, 5, (short) 6));
225 
226     try {
227       m = Main.class.getDeclaredMethod("thrower");
228       System.out.println(Arrays.toString(m.getParameterTypes()));
229       show(m.invoke(null));
230       System.out.println("************* should have thrown!");
231     } catch (InvocationTargetException expected) {
232       System.out.println("got expected InvocationTargetException");
233     }
234   }
235 
thrower()236   private static void thrower() {
237     throw new ArithmeticException("surprise!");
238   }
239 
sumArray(int[] xs)240   private static int sumArray(int[] xs) {
241     int result = 0;
242     for (int x : xs) {
243       result += x;
244     }
245     return result;
246   }
247 
concat(String[] strings)248   private static String concat(String[] strings) {
249     String result = "";
250     for (String s : strings) {
251       result += s;
252     }
253     return result;
254   }
255 
IV(int i)256   private static void IV(int i) {
257     System.out.println(i);
258   }
259 
IIV(int i, int j)260   private static void IIV(int i, int j) {
261     System.out.println(i + " " + j);
262   }
263 
III(int i, int j)264   private static int III(int i, int j) {
265     System.out.println(i + " " + j);
266     return i + j;
267   }
268 
ZBCDFIJSV(boolean z, byte b, char c, double d, float f, int i, long l, short s)269   private static void ZBCDFIJSV(boolean z, byte b, char c, double d, float f, int i, long l, short s) {
270     System.out.println(z + " " + b + " " + c + " " + d + " " + f + " " + i + " " + l + " " + s);
271   }
272 
ZBCDLFIJSV(boolean z, byte b, char c, double d, String string, float f, int i, long l, short s)273   private static void ZBCDLFIJSV(boolean z, byte b, char c, double d, String string, float f, int i, long l, short s) {
274     System.out.println(z + " " + b + " " + c + " " + d + " " + " " + string + " " + f + " " + i + " " + l + " " + s);
275   }
276 
testConstructorReflection()277   public static void testConstructorReflection() throws Exception {
278     Constructor<?> ctor;
279 
280     ctor = String.class.getConstructor(new Class[0]);
281     show(ctor.newInstance((Object[]) null));
282 
283     ctor = String.class.getConstructor(char[].class, int.class, int.class);
284     show(ctor.newInstance(new char[] { '\u2714', 'y', 'z', '!' }, 1, 2));
285   }
286 
testPackagePrivateConstructor()287   private static void testPackagePrivateConstructor() {
288     try {
289       Class<?> c = Class.forName("sub.PPClass");
290       Constructor cons = c.getConstructor();
291       cons.newInstance();
292       throw new RuntimeException("Expected IllegalAccessException.");
293     } catch (IllegalAccessException e) {
294       // Expected.
295     } catch (Exception e) {
296       // Error.
297       e.printStackTrace();
298     }
299   }
300 
testPackagePrivateAccessibleConstructor()301   private static void testPackagePrivateAccessibleConstructor() {
302     try {
303       Class<?> c = Class.forName("sub.PPClass");
304       Constructor cons = c.getConstructor();
305       cons.setAccessible(true);  // ensure we prevent IllegalAccessException
306       cons.newInstance();
307     } catch (Exception e) {
308       // Error.
309       e.printStackTrace();
310     }
311   }
312 
main(String[] args)313   public static void main(String[] args) throws Exception {
314     testFieldReflection();
315     testMethodReflection();
316     testConstructorReflection();
317     testPackagePrivateConstructor();
318     testPackagePrivateAccessibleConstructor();
319   }
320 }
321