blob: 638fb470797ef3fbb26e35c9c69b6e3b091b2756 [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();
27 reflection();
28 stringIndex();
29 }
30
31 private static void assertEquals(String expected, String actual) {
32 if (expected == null && actual == null) {
33 return;
34 }
35 if (expected != null && expected.equals(actual)) {
36 return;
37 }
38 throw new AssertionError("not equal\n" +
39 "expected: " + expected + "\n" +
40 "actual: " + actual);
41 }
42
43 private static void fail() {
44 throw new AssertionError();
45 }
46
47 private static void arrayAccess() throws Exception {
48 byte[] bs = new byte[1];
49 double[] ds = new double[1];
50 Object[] os = new Object[1];
51
52 // aput
53 try {
54 bs[2] = 0;
55 fail();
56 } catch (ArrayIndexOutOfBoundsException ex) {
57 assertEquals("length=1; index=2", ex.getMessage());
58 }
59
60 // aget
61 try {
62 byte b = bs[2];
63 fail();
64 } catch (ArrayIndexOutOfBoundsException ex) {
65 assertEquals("length=1; index=2", ex.getMessage());
66 }
67
68 // aput-wide
69 try {
70 ds[2] = 0.0;
71 fail();
72 } catch (ArrayIndexOutOfBoundsException ex) {
73 assertEquals("length=1; index=2", ex.getMessage());
74 }
75
76 // aget-wide
77 try {
78 double d = ds[2];
79 fail();
80 } catch (ArrayIndexOutOfBoundsException ex) {
81 assertEquals("length=1; index=2", ex.getMessage());
82 }
83
84 // aput-object
85 try {
86 os[2] = null;
87 fail();
88 } catch (ArrayIndexOutOfBoundsException ex) {
89 assertEquals("length=1; index=2", ex.getMessage());
90 }
91
92 // aget-object
93 try {
94 Object o = os[2];
95 fail();
96 } catch (ArrayIndexOutOfBoundsException ex) {
97 assertEquals("length=1; index=2", ex.getMessage());
98 }
99 }
100
101 private static void arrayStore() throws Exception {
102 try {
103 Object[] array = new String[10];
104 Object o = new Exception();
105 array[0] = o;
106 fail();
107 } catch (ArrayStoreException ex) {
108 assertEquals("java.lang.Exception cannot be stored in an array of type java.lang.String[]",
109 ex.getMessage());
110 }
111
112 try {
113 Object[] array = new C[10][];
114 Object o = new Integer(5);
115 array[0] = o;
116 fail();
117 } catch (ArrayStoreException ex) {
118 assertEquals("java.lang.Integer cannot be stored in an array of type Main$C[][]",
119 ex.getMessage());
120 }
121
122 try {
123 Object[] array = new Float[10][];
124 Object o = new C[4];
125 array[0] = o;
126 fail();
127 } catch (ArrayStoreException ex) {
128 assertEquals("Main$C[] cannot be stored in an array of type java.lang.Float[][]",
129 ex.getMessage());
130 }
131
132 try {
133 String[] src = new String[] { null, null, null, null, "hello", "goodbye" };
134 Integer[] dst = new Integer[10];
135 System.arraycopy(src, 1, dst, 0, 5);
136 } catch (ArrayStoreException ex) {
137 assertEquals("source[4] of type java.lang.String cannot be stored in destination array of type java.lang.Integer[]",
138 ex.getMessage());
139 }
140
141 try {
142 String[] src = new String[1];
143 int[] dst = new int[1];
144 System.arraycopy(src, 0, dst, 0, 1);
145 } catch (ArrayStoreException ex) {
146 assertEquals("Incompatible types: src=java.lang.String[], dst=int[]", ex.getMessage());
147 }
148
149 try {
150 float[] src = new float[1];
151 Runnable[] dst = new Runnable[1];
152 System.arraycopy(src, 0, dst, 0, 1);
153 } catch (ArrayStoreException ex) {
154 assertEquals("Incompatible types: src=float[], dst=java.lang.Runnable[]", ex.getMessage());
155 }
156
157 try {
158 boolean[] src = new boolean[1];
159 double[][] dst = new double[1][];
160 System.arraycopy(src, 0, dst, 0, 1);
161 } catch (ArrayStoreException ex) {
162 assertEquals("Incompatible types: src=boolean[], dst=double[][]", ex.getMessage());
163 }
164
165 try {
166 String src = "hello";
167 Object[] dst = new Object[1];
168 System.arraycopy(src, 0, dst, 0, 1);
169 } catch (ArrayStoreException ex) {
170 assertEquals("source of type java.lang.String is not an array", ex.getMessage());
171 }
172
173 try {
174 Object[] src = new Object[1];
175 Integer dst = new Integer(5);
176 System.arraycopy(src, 0, dst, 0, 1);
177 } catch (ArrayStoreException ex) {
178 assertEquals("destination of type java.lang.Integer is not an array", ex.getMessage());
179 }
180
181 // This test demonstrates that the exception message complains
182 // about the source in cases where neither source nor
183 // destination is an array.
184 try {
185 System.arraycopy(new C(), 0, "hello", 0, 1);
186 } catch (ArrayStoreException ex) {
187 assertEquals("source of type Main$C is not an array", ex.getMessage());
188 }
189 }
190
191 private static void classCast() throws Exception {
192 // Reference types.
193 try {
194 Object o = new Exception();
195 String s = (String) o;
196 fail();
197 } catch (ClassCastException ex) {
198 assertEquals("java.lang.Exception cannot be cast to java.lang.String", ex.getMessage());
199 }
200
201 // Arrays of reference types.
202 try {
203 Object o = (C) makeArray(String.class);
204 fail();
205 } catch (ClassCastException ex) {
206 assertEquals("java.lang.String[] cannot be cast to Main$C", ex.getMessage());
207 }
208
209 // Arrays of primitives.
210 try {
211 Object o = (C) makeArray(float.class);
212 fail();
213 } catch (ClassCastException ex) {
214 assertEquals("float[] cannot be cast to Main$C", ex.getMessage());
215 }
216
217 // Multi-dimensional arrays of primitives.
218 try {
219 Object o = (C) makeArray(char[].class);
220 fail();
221 } catch (ClassCastException ex) {
222 assertEquals("char[][] cannot be cast to Main$C", ex.getMessage());
223 }
224
225 // Multi-dimensional arrays of references.
226 try {
227 Object o = (Object[][][]) makeInteger();
228 fail();
229 } catch (ClassCastException ex) {
230 assertEquals("java.lang.Integer cannot be cast to java.lang.Object[][][]", ex.getMessage());
231 }
232 }
233
234 static class C { }
235
236 /**
237 * Helper for testCastOperator and testCastOperatorWithArrays. It's important that the
238 * return type is Object, since otherwise the compiler will just reject the code.
239 */
240 private static Object makeInteger() {
241 return new Integer(5);
242 }
243
244 /**
245 * Helper for testCastOperatorWithArrays. It's important that
246 * the return type is Object.
247 */
248 private static Object makeArray(Class c) {
249 return Array.newInstance(c, 1);
250 }
251
252 private static void classNotFound() throws Exception {
253 try {
254 // There is no such thing as an array of void.
255 Class.forName("[V");
256 fail();
257 } catch (ClassNotFoundException ex) {
258 assertEquals("Invalid name: [V", ex.getMessage());
259 }
260
261 try {
262 // This class name is valid, but doesn't exist.
263 Class.forName("package.Class");
264 fail();
265 } catch (ClassNotFoundException ex) {
266 assertEquals("package.Class", ex.getMessage());
267 }
268
269 try {
270 // This array class name is valid, but the type doesn't exist.
271 Class.forName("[[Lpackage.Class;");
272 fail();
273 } catch (ClassNotFoundException ex) {
274 assertEquals("[[Lpackage.Class;", ex.getMessage());
275 }
276 }
277
278 private static void reflection() throws Exception {
279 // Can't assign Integer to a String field.
280 try {
281 Field field = A.class.getField("b");
282 field.set(new A(), 5);
283 fail();
284 } catch (IllegalArgumentException expected) {
285 assertEquals("field A.b has type java.lang.String, got java.lang.Integer", expected.getMessage());
286 }
287
288 // Can't unbox null to a primitive.
289 try {
290 Field field = A.class.getField("i");
291 field.set(new A(), null);
292 fail();
293 } catch (IllegalArgumentException expected) {
294 assertEquals("field A.i has type int, got null", expected.getMessage());
295 }
296
297 // Can't unbox String to a primitive.
298 try {
299 Field field = A.class.getField("i");
300 field.set(new A(), "hello, world!");
301 fail();
302 } catch (IllegalArgumentException expected) {
303 assertEquals("field A.i has type int, got java.lang.String", expected.getMessage());
304 }
305
306 // Can't pass an Integer as a String.
307 try {
308 Method m = A.class.getMethod("m", int.class, String.class);
309 m.invoke(new A(), 2, 2);
310 fail();
311 } catch (IllegalArgumentException expected) {
312 assertEquals("method A.m argument 2 has type java.lang.String, got java.lang.Integer", expected.getMessage());
313 }
314
315 // Can't pass null as an int.
316 try {
317 Method m = A.class.getMethod("m", int.class, String.class);
318 m.invoke(new A(), null, "");
319 fail();
320 } catch (IllegalArgumentException expected) {
321 assertEquals("method A.m argument 1 has type int, got null", expected.getMessage());
322 }
323 }
324
325 private static void stringIndex() throws Exception {
326 // charAt too small.
327 try {
328 "hello".charAt(-1);
329 fail();
330 } catch (StringIndexOutOfBoundsException ex) {
331 assertEquals("length=5; index=-1", ex.getMessage());
332 }
333
334 // charAt too big.
335 try {
336 "hello".charAt(7);
337 fail();
338 } catch (StringIndexOutOfBoundsException ex) {
339 assertEquals("length=5; index=7", ex.getMessage());
340 }
341
342 // substring too big.
343 try {
344 "hello there".substring(9,14);
345 fail();
346 } catch (StringIndexOutOfBoundsException ex) {
347 assertEquals("length=11; regionStart=9; regionLength=5", ex.getMessage());
348 }
349 }
350}
351
352class A {
353 public String b;
354 public int i;
355 public void m(int i, String s) {}
356}