blob: 24ee6e0eb324dd343887fd8ffdb023fd886ed82b [file] [log] [blame]
Elliott Hughes72e401c2012-06-19 15:47:23 -07001/*
2 * Copyright (C) 2012 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
17import java.lang.reflect.Array;
18import java.lang.reflect.Field;
19import java.lang.reflect.Method;
20
21public class Main {
22 public static void main(String[] args) throws Exception {
23 arrayAccess();
24 arrayStore();
25 classCast();
26 classNotFound();
Elliott Hughes6fcce302012-06-19 16:54:19 -070027 negativeArraySize();
28 nullPointers();
Elliott Hughes72e401c2012-06-19 15:47:23 -070029 reflection();
30 stringIndex();
31 }
32
33 private static void assertEquals(String expected, String actual) {
34 if (expected == null && actual == null) {
35 return;
36 }
37 if (expected != null && expected.equals(actual)) {
38 return;
39 }
40 throw new AssertionError("not equal\n" +
41 "expected: " + expected + "\n" +
42 "actual: " + actual);
43 }
44
45 private static void fail() {
46 throw new AssertionError();
47 }
48
49 private static void arrayAccess() throws Exception {
50 byte[] bs = new byte[1];
51 double[] ds = new double[1];
52 Object[] os = new Object[1];
53
54 // aput
55 try {
56 bs[2] = 0;
57 fail();
58 } catch (ArrayIndexOutOfBoundsException ex) {
59 assertEquals("length=1; index=2", ex.getMessage());
60 }
61
62 // aget
63 try {
64 byte b = bs[2];
65 fail();
66 } catch (ArrayIndexOutOfBoundsException ex) {
67 assertEquals("length=1; index=2", ex.getMessage());
68 }
69
70 // aput-wide
71 try {
72 ds[2] = 0.0;
73 fail();
74 } catch (ArrayIndexOutOfBoundsException ex) {
75 assertEquals("length=1; index=2", ex.getMessage());
76 }
77
78 // aget-wide
79 try {
80 double d = ds[2];
81 fail();
82 } catch (ArrayIndexOutOfBoundsException ex) {
83 assertEquals("length=1; index=2", ex.getMessage());
84 }
85
86 // aput-object
87 try {
88 os[2] = null;
89 fail();
90 } catch (ArrayIndexOutOfBoundsException ex) {
91 assertEquals("length=1; index=2", ex.getMessage());
92 }
93
94 // aget-object
95 try {
96 Object o = os[2];
97 fail();
98 } catch (ArrayIndexOutOfBoundsException ex) {
99 assertEquals("length=1; index=2", ex.getMessage());
100 }
101 }
102
103 private static void arrayStore() throws Exception {
104 try {
105 Object[] array = new String[10];
106 Object o = new Exception();
107 array[0] = o;
108 fail();
109 } catch (ArrayStoreException ex) {
110 assertEquals("java.lang.Exception cannot be stored in an array of type java.lang.String[]",
111 ex.getMessage());
112 }
113
114 try {
115 Object[] array = new C[10][];
116 Object o = new Integer(5);
117 array[0] = o;
118 fail();
119 } catch (ArrayStoreException ex) {
120 assertEquals("java.lang.Integer cannot be stored in an array of type Main$C[][]",
121 ex.getMessage());
122 }
123
124 try {
125 Object[] array = new Float[10][];
126 Object o = new C[4];
127 array[0] = o;
128 fail();
129 } catch (ArrayStoreException ex) {
130 assertEquals("Main$C[] cannot be stored in an array of type java.lang.Float[][]",
131 ex.getMessage());
132 }
133
134 try {
135 String[] src = new String[] { null, null, null, null, "hello", "goodbye" };
136 Integer[] dst = new Integer[10];
137 System.arraycopy(src, 1, dst, 0, 5);
138 } catch (ArrayStoreException ex) {
139 assertEquals("source[4] of type java.lang.String cannot be stored in destination array of type java.lang.Integer[]",
140 ex.getMessage());
141 }
142
143 try {
144 String[] src = new String[1];
145 int[] dst = new int[1];
146 System.arraycopy(src, 0, dst, 0, 1);
147 } catch (ArrayStoreException ex) {
148 assertEquals("Incompatible types: src=java.lang.String[], dst=int[]", ex.getMessage());
149 }
150
151 try {
152 float[] src = new float[1];
153 Runnable[] dst = new Runnable[1];
154 System.arraycopy(src, 0, dst, 0, 1);
155 } catch (ArrayStoreException ex) {
156 assertEquals("Incompatible types: src=float[], dst=java.lang.Runnable[]", ex.getMessage());
157 }
158
159 try {
160 boolean[] src = new boolean[1];
161 double[][] dst = new double[1][];
162 System.arraycopy(src, 0, dst, 0, 1);
163 } catch (ArrayStoreException ex) {
164 assertEquals("Incompatible types: src=boolean[], dst=double[][]", ex.getMessage());
165 }
166
167 try {
168 String src = "hello";
169 Object[] dst = new Object[1];
170 System.arraycopy(src, 0, dst, 0, 1);
171 } catch (ArrayStoreException ex) {
172 assertEquals("source of type java.lang.String is not an array", ex.getMessage());
173 }
174
175 try {
176 Object[] src = new Object[1];
177 Integer dst = new Integer(5);
178 System.arraycopy(src, 0, dst, 0, 1);
179 } catch (ArrayStoreException ex) {
180 assertEquals("destination of type java.lang.Integer is not an array", ex.getMessage());
181 }
182
183 // This test demonstrates that the exception message complains
184 // about the source in cases where neither source nor
185 // destination is an array.
186 try {
187 System.arraycopy(new C(), 0, "hello", 0, 1);
188 } catch (ArrayStoreException ex) {
189 assertEquals("source of type Main$C is not an array", ex.getMessage());
190 }
191 }
192
193 private static void classCast() throws Exception {
194 // Reference types.
195 try {
196 Object o = new Exception();
197 String s = (String) o;
198 fail();
199 } catch (ClassCastException ex) {
200 assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage());
201 }
202
203 // Arrays of reference types.
204 try {
205 Object o = (C) makeArray(String.class);
206 fail();
207 } catch (ClassCastException ex) {
208 assertEquals("java.lang.String[] cannot be cast to Main$C", ex.getMessage());
209 }
210
211 // Arrays of primitives.
212 try {
213 Object o = (C) makeArray(float.class);
214 fail();
215 } catch (ClassCastException ex) {
216 assertEquals("float[] cannot be cast to Main$C", ex.getMessage());
217 }
218
219 // Multi-dimensional arrays of primitives.
220 try {
221 Object o = (C) makeArray(char[].class);
222 fail();
223 } catch (ClassCastException ex) {
224 assertEquals("char[][] cannot be cast to Main$C", ex.getMessage());
225 }
226
227 // Multi-dimensional arrays of references.
228 try {
229 Object o = (Object[][][]) makeInteger();
230 fail();
231 } catch (ClassCastException ex) {
232 assertEquals("java.lang.Integer cannot be cast to java.lang.Object[][][]", ex.getMessage());
233 }
234 }
235
236 static class C { }
237
238 /**
239 * Helper for testCastOperator and testCastOperatorWithArrays. It's important that the
240 * return type is Object, since otherwise the compiler will just reject the code.
241 */
242 private static Object makeInteger() {
243 return new Integer(5);
244 }
245
246 /**
247 * Helper for testCastOperatorWithArrays. It's important that
248 * the return type is Object.
249 */
250 private static Object makeArray(Class c) {
251 return Array.newInstance(c, 1);
252 }
253
254 private static void classNotFound() throws Exception {
255 try {
256 // There is no such thing as an array of void.
257 Class.forName("[V");
258 fail();
259 } catch (ClassNotFoundException ex) {
260 assertEquals("Invalid name: [V", ex.getMessage());
261 }
262
263 try {
264 // This class name is valid, but doesn't exist.
265 Class.forName("package.Class");
266 fail();
267 } catch (ClassNotFoundException ex) {
268 assertEquals("package.Class", ex.getMessage());
269 }
270
271 try {
272 // This array class name is valid, but the type doesn't exist.
273 Class.forName("[[Lpackage.Class;");
274 fail();
275 } catch (ClassNotFoundException ex) {
276 assertEquals("[[Lpackage.Class;", ex.getMessage());
277 }
278 }
279
Elliott Hughes6fcce302012-06-19 16:54:19 -0700280 private static void negativeArraySize() throws Exception {
281 try {
282 int[] is = new int[-123];
283 fail();
284 } catch (NegativeArraySizeException ex) {
285 assertEquals("-123", ex.getMessage());
286 }
287 }
288
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200289 // Defeat the fact that null's are untyped for precise detail message creation with quickening.
290 private static Object returnNullObject() {
291 return null;
292 }
293
294 private static A returnNullA() {
295 return null;
296 }
297
Elliott Hughes6fcce302012-06-19 16:54:19 -0700298 private static void nullPointers() throws Exception {
299 // Invoke method.
300 try {
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200301 Object o = returnNullObject();
Elliott Hughes6fcce302012-06-19 16:54:19 -0700302 o.hashCode();
303 fail();
304 } catch (NullPointerException ex) {
305 assertEquals("Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference", ex.getMessage());
306 }
307
308 // Read field.
309 try {
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200310 A a = returnNullA();
Elliott Hughes6fcce302012-06-19 16:54:19 -0700311 int i = a.i;
312 fail();
313 } catch (NullPointerException ex) {
314 assertEquals("Attempt to read from field 'int A.i' on a null object reference", ex.getMessage());
315 }
316
317 // Write field.
318 try {
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200319 A a = returnNullA();
Elliott Hughes6fcce302012-06-19 16:54:19 -0700320 a.i = 1;
321 fail();
322 } catch (NullPointerException ex) {
323 assertEquals("Attempt to write to field 'int A.i' on a null object reference", ex.getMessage());
324 }
325
326 // Read array.
327 try {
328 int[] is = null;
329 int i = is[0];
330 fail();
331 } catch (NullPointerException ex) {
332 assertEquals("Attempt to read from null array", ex.getMessage());
333 }
334
335 // Write array.
336 try {
337 int[] is = null;
338 is[0] = 1;
339 fail();
340 } catch (NullPointerException ex) {
341 assertEquals("Attempt to write to null array", ex.getMessage());
342 }
343
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200344 // Array length.
Elliott Hughes6fcce302012-06-19 16:54:19 -0700345 try {
346 int[] is = null;
347 int i = is.length;
348 fail();
349 } catch (NullPointerException ex) {
350 assertEquals("Attempt to get length of null array", ex.getMessage());
351 }
352 }
353
Elliott Hughes72e401c2012-06-19 15:47:23 -0700354 private static void reflection() throws Exception {
355 // Can't assign Integer to a String field.
356 try {
357 Field field = A.class.getField("b");
358 field.set(new A(), 5);
359 fail();
360 } catch (IllegalArgumentException expected) {
361 assertEquals("field A.b has type java.lang.String, got java.lang.Integer", expected.getMessage());
362 }
363
364 // Can't unbox null to a primitive.
365 try {
366 Field field = A.class.getField("i");
367 field.set(new A(), null);
368 fail();
369 } catch (IllegalArgumentException expected) {
370 assertEquals("field A.i has type int, got null", expected.getMessage());
371 }
372
373 // Can't unbox String to a primitive.
374 try {
375 Field field = A.class.getField("i");
376 field.set(new A(), "hello, world!");
377 fail();
378 } catch (IllegalArgumentException expected) {
379 assertEquals("field A.i has type int, got java.lang.String", expected.getMessage());
380 }
381
382 // Can't pass an Integer as a String.
383 try {
384 Method m = A.class.getMethod("m", int.class, String.class);
385 m.invoke(new A(), 2, 2);
386 fail();
387 } catch (IllegalArgumentException expected) {
388 assertEquals("method A.m argument 2 has type java.lang.String, got java.lang.Integer", expected.getMessage());
389 }
390
391 // Can't pass null as an int.
392 try {
393 Method m = A.class.getMethod("m", int.class, String.class);
394 m.invoke(new A(), null, "");
395 fail();
396 } catch (IllegalArgumentException expected) {
397 assertEquals("method A.m argument 1 has type int, got null", expected.getMessage());
398 }
Elliott Hughes6fcce302012-06-19 16:54:19 -0700399
400 try {
401 Method m = String.class.getMethod("charAt", int.class);
402 m.invoke("hello"); // Wrong number of arguments.
403 fail();
404 } catch (IllegalArgumentException iae) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800405 assertEquals("Wrong number of arguments; expected 1, got 0", iae.getMessage());
Elliott Hughes6fcce302012-06-19 16:54:19 -0700406 }
407 try {
408 Method m = String.class.getMethod("charAt", int.class);
409 m.invoke("hello", "world"); // Wrong type.
410 fail();
411 } catch (IllegalArgumentException iae) {
412 assertEquals("method java.lang.String.charAt argument 1 has type int, got java.lang.String", iae.getMessage());
413 }
414 try {
415 Method m = String.class.getMethod("charAt", int.class);
416 m.invoke("hello", (Object) null); // Null for a primitive argument.
417 fail();
418 } catch (IllegalArgumentException iae) {
419 assertEquals("method java.lang.String.charAt argument 1 has type int, got null", iae.getMessage());
420 }
421 try {
422 Method m = String.class.getMethod("charAt", int.class);
423 m.invoke(new Integer(5)); // Wrong type for 'this'.
424 fail();
425 } catch (IllegalArgumentException iae) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800426 assertEquals("Expected receiver of type java.lang.String, but got java.lang.Integer", iae.getMessage());
Elliott Hughes6fcce302012-06-19 16:54:19 -0700427 }
428 try {
429 Method m = String.class.getMethod("charAt", int.class);
430 m.invoke(null); // Null for 'this'.
431 fail();
432 } catch (NullPointerException npe) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800433 assertEquals("null receiver", npe.getMessage());
Elliott Hughes6fcce302012-06-19 16:54:19 -0700434 }
Elliott Hughes72e401c2012-06-19 15:47:23 -0700435 }
436
437 private static void stringIndex() throws Exception {
438 // charAt too small.
439 try {
440 "hello".charAt(-1);
441 fail();
442 } catch (StringIndexOutOfBoundsException ex) {
443 assertEquals("length=5; index=-1", ex.getMessage());
444 }
445
446 // charAt too big.
447 try {
448 "hello".charAt(7);
449 fail();
450 } catch (StringIndexOutOfBoundsException ex) {
451 assertEquals("length=5; index=7", ex.getMessage());
452 }
453
454 // substring too big.
455 try {
456 "hello there".substring(9,14);
457 fail();
458 } catch (StringIndexOutOfBoundsException ex) {
459 assertEquals("length=11; regionStart=9; regionLength=5", ex.getMessage());
460 }
461 }
462}
463
464class A {
465 public String b;
466 public int i;
467 public void m(int i, String s) {}
468}