1 /* 2 * Copyright (C) 2008 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 other.PublicClass; 18 import java.lang.reflect.Field; 19 import java.lang.reflect.Method; 20 21 /* 22 * Test field access through reflection. 23 */ 24 public class Main { main(String[] args)25 public static void main(String[] args) { 26 SubClass.main(null); 27 28 try { 29 GetNonexistent.main(null); 30 System.err.println("Not expected to succeed"); 31 } catch (VerifyError fe) { 32 // dalvik 33 System.out.println("Got expected failure"); 34 } catch (NoSuchFieldError nsfe) { 35 // reference 36 System.out.println("Got expected failure"); 37 } 38 } 39 40 /* 41 * Get the field specified by "field" from "obj". 42 * 43 * "type" determines which "get" call is made, e.g. 'B' turns into 44 * field.getByte(). 45 * 46 * The "expectedException" must match the class of the exception thrown, 47 * or be null if no exception was expected. 48 * 49 * On success, the boxed value retrieved is returned. 50 */ getValue(Field field, Object obj, char type, Class expectedException)51 public Object getValue(Field field, Object obj, char type, 52 Class expectedException) { 53 Object result = null; 54 try { 55 switch (type) { 56 case 'Z': 57 result = field.getBoolean(obj); 58 break; 59 case 'B': 60 result = field.getByte(obj); 61 break; 62 case 'S': 63 result = field.getShort(obj); 64 break; 65 case 'C': 66 result = field.getChar(obj); 67 break; 68 case 'I': 69 result = field.getInt(obj); 70 break; 71 case 'J': 72 result = field.getLong(obj); 73 break; 74 case 'F': 75 result = field.getFloat(obj); 76 break; 77 case 'D': 78 result = field.getDouble(obj); 79 break; 80 case 'L': 81 result = field.get(obj); 82 break; 83 default: 84 throw new RuntimeException("bad type '" + type + "'"); 85 } 86 87 /* success; expected? */ 88 if (expectedException != null) { 89 System.err.println("ERROR: call succeeded for field " + field + 90 " with a read of type '" + type + 91 "', was expecting " + expectedException); 92 Thread.dumpStack(); 93 } 94 } catch (Exception ex) { 95 if (expectedException == null) { 96 System.err.println("ERROR: call failed unexpectedly: " 97 + ex.getClass()); 98 ex.printStackTrace(); 99 } else { 100 if (!expectedException.equals(ex.getClass())) { 101 System.err.println("ERROR: incorrect exception: wanted " 102 + expectedException.getName() + ", got " 103 + ex.getClass()); 104 ex.printStackTrace(); 105 } 106 } 107 } 108 109 return result; 110 } 111 } 112 113 /* 114 * Local class with some fields. 115 */ 116 class SamePackage { 117 public boolean samePackagePublicBooleanInstanceField = true; 118 public byte samePackagePublicByteInstanceField = 2; 119 public char samePackagePublicCharInstanceField = 3; 120 public short samePackagePublicShortInstanceField = 4; 121 public int samePackagePublicIntInstanceField = 5; 122 public long samePackagePublicLongInstanceField = 6; 123 public float samePackagePublicFloatInstanceField = 7.0f; 124 public double samePackagePublicDoubleInstanceField = 8.0; 125 public Object samePackagePublicObjectInstanceField = "9"; 126 127 protected boolean samePackageProtectedBooleanInstanceField = true; 128 protected byte samePackageProtectedByteInstanceField = 10; 129 protected char samePackageProtectedCharInstanceField = 11; 130 protected short samePackageProtectedShortInstanceField = 12; 131 protected int samePackageProtectedIntInstanceField = 13; 132 protected long samePackageProtectedLongInstanceField = 14; 133 protected float samePackageProtectedFloatInstanceField = 15.0f; 134 protected double samePackageProtectedDoubleInstanceField = 16.0; 135 protected Object samePackageProtectedObjectInstanceField = "17"; 136 137 private boolean samePackagePrivateBooleanInstanceField = true; 138 private byte samePackagePrivateByteInstanceField = 18; 139 private char samePackagePrivateCharInstanceField = 19; 140 private short samePackagePrivateShortInstanceField = 20; 141 private int samePackagePrivateIntInstanceField = 21; 142 private long samePackagePrivateLongInstanceField = 22; 143 private float samePackagePrivateFloatInstanceField = 23.0f; 144 private double samePackagePrivateDoubleInstanceField = 24.0; 145 private Object samePackagePrivateObjectInstanceField = "25"; 146 147 /* package */ boolean samePackagePackageBooleanInstanceField = true; 148 /* package */ byte samePackagePackageByteInstanceField = 26; 149 /* package */ char samePackagePackageCharInstanceField = 27; 150 /* package */ short samePackagePackageShortInstanceField = 28; 151 /* package */ int samePackagePackageIntInstanceField = 29; 152 /* package */ long samePackagePackageLongInstanceField = 30; 153 /* package */ float samePackagePackageFloatInstanceField = 31.0f; 154 /* package */ double samePackagePackageDoubleInstanceField = 32.0; 155 /* package */ Object samePackagePackageObjectInstanceField = "33"; 156 157 public static boolean samePackagePublicBooleanStaticField = true; 158 public static byte samePackagePublicByteStaticField = 34; 159 public static char samePackagePublicCharStaticField = 35; 160 public static short samePackagePublicShortStaticField = 36; 161 public static int samePackagePublicIntStaticField = 37; 162 public static long samePackagePublicLongStaticField = 38; 163 public static float samePackagePublicFloatStaticField = 39.0f; 164 public static double samePackagePublicDoubleStaticField = 40.0; 165 public static Object samePackagePublicObjectStaticField = "41"; 166 167 protected static boolean samePackageProtectedBooleanStaticField = true; 168 protected static byte samePackageProtectedByteStaticField = 42; 169 protected static char samePackageProtectedCharStaticField = 43; 170 protected static short samePackageProtectedShortStaticField = 44; 171 protected static int samePackageProtectedIntStaticField = 45; 172 protected static long samePackageProtectedLongStaticField = 46; 173 protected static float samePackageProtectedFloatStaticField = 47.0f; 174 protected static double samePackageProtectedDoubleStaticField = 48.0; 175 protected static Object samePackageProtectedObjectStaticField = "49"; 176 177 private static boolean samePackagePrivateBooleanStaticField = true; 178 private static byte samePackagePrivateByteStaticField = 50; 179 private static char samePackagePrivateCharStaticField = 51; 180 private static short samePackagePrivateShortStaticField = 52; 181 private static int samePackagePrivateIntStaticField = 53; 182 private static long samePackagePrivateLongStaticField = 54; 183 private static float samePackagePrivateFloatStaticField = 55.0f; 184 private static double samePackagePrivateDoubleStaticField = 56.0; 185 private static Object samePackagePrivateObjectStaticField = "57"; 186 187 /* package */ static boolean samePackagePackageBooleanStaticField = true; 188 /* package */ static byte samePackagePackageByteStaticField = 58; 189 /* package */ static char samePackagePackageCharStaticField = 59; 190 /* package */ static short samePackagePackageShortStaticField = 60; 191 /* package */ static int samePackagePackageIntStaticField = 61; 192 /* package */ static long samePackagePackageLongStaticField = 62; 193 /* package */ static float samePackagePackageFloatStaticField = 63.0f; 194 /* package */ static double samePackagePackageDoubleStaticField = 64.0; 195 /* package */ static Object samePackagePackageObjectStaticField = "65"; 196 samePublicMethod()197 public void samePublicMethod() { } sameProtectedMethod()198 protected void sameProtectedMethod() { } samePrivateMethod()199 private void samePrivateMethod() { } samePackageMethod()200 /* package */ void samePackageMethod() { } 201 } 202 203 /* 204 * This is a sub-class of other.PublicClass, which should be allowed to access 205 * the various protected fields declared by other.PublicClass and its parent 206 * other.ProtectedClass. 207 */ 208 class SubClass extends PublicClass { 209 /* 210 * Perform the various tests. 211 * 212 * localInst.getValue() is performed using an instance of Main as the 213 * source of the reflection call. otherInst.getValue() uses a subclass 214 * of OtherPackage as the source. 215 */ main(String[] args)216 public static void main(String[] args) { 217 SubClass subOther = new SubClass(); 218 subOther.doDirectTests(); 219 subOther.doReflectionTests(); 220 } 221 check(boolean b)222 private static void check(boolean b) { 223 if (!b) { 224 throw new Error("Test failed"); 225 } 226 } 227 doDirectTests()228 public void doDirectTests() { 229 check(otherProtectedClassPublicBooleanInstanceField == true); 230 check(otherProtectedClassPublicByteInstanceField == 2); 231 check(otherProtectedClassPublicCharInstanceField == 3); 232 check(otherProtectedClassPublicShortInstanceField == 4); 233 check(otherProtectedClassPublicIntInstanceField == 5); 234 check(otherProtectedClassPublicLongInstanceField == 6); 235 check(otherProtectedClassPublicFloatInstanceField == 7.0f); 236 check(otherProtectedClassPublicDoubleInstanceField == 8.0); 237 check(otherProtectedClassPublicObjectInstanceField == "9"); 238 239 check(otherProtectedClassProtectedBooleanInstanceField == true); 240 check(otherProtectedClassProtectedByteInstanceField == 10); 241 check(otherProtectedClassProtectedCharInstanceField == 11); 242 check(otherProtectedClassProtectedShortInstanceField == 12); 243 check(otherProtectedClassProtectedIntInstanceField == 13); 244 check(otherProtectedClassProtectedLongInstanceField == 14); 245 check(otherProtectedClassProtectedFloatInstanceField == 15.0f); 246 check(otherProtectedClassProtectedDoubleInstanceField == 16.0); 247 check(otherProtectedClassProtectedObjectInstanceField == "17"); 248 249 // check(otherProtectedClassPrivateBooleanInstanceField == true); 250 // check(otherProtectedClassPrivateByteInstanceField == 18); 251 // check(otherProtectedClassPrivateCharInstanceField == 19); 252 // check(otherProtectedClassPrivateShortInstanceField == 20); 253 // check(otherProtectedClassPrivateIntInstanceField == 21); 254 // check(otherProtectedClassPrivateLongInstanceField == 22); 255 // check(otherProtectedClassPrivateFloatInstanceField == 23.0f); 256 // check(otherProtectedClassPrivateDoubleInstanceField == 24.0); 257 // check(otherProtectedClassPrivateObjectInstanceField == "25"); 258 259 // check(otherProtectedClassPackageBooleanInstanceField == true); 260 // check(otherProtectedClassPackageByteInstanceField == 26); 261 // check(otherProtectedClassPackageCharInstanceField == 27); 262 // check(otherProtectedClassPackageShortInstanceField == 28); 263 // check(otherProtectedClassPackageIntInstanceField == 29); 264 // check(otherProtectedClassPackageLongInstanceField == 30); 265 // check(otherProtectedClassPackageFloatInstanceField == 31.0f); 266 // check(otherProtectedClassPackageDoubleInstanceField == 32.0); 267 // check(otherProtectedClassPackageObjectInstanceField == "33"); 268 269 check(otherProtectedClassPublicBooleanStaticField == true); 270 check(otherProtectedClassPublicByteStaticField == 34); 271 check(otherProtectedClassPublicCharStaticField == 35); 272 check(otherProtectedClassPublicShortStaticField == 36); 273 check(otherProtectedClassPublicIntStaticField == 37); 274 check(otherProtectedClassPublicLongStaticField == 38); 275 check(otherProtectedClassPublicFloatStaticField == 39.0f); 276 check(otherProtectedClassPublicDoubleStaticField == 40.0); 277 check(otherProtectedClassPublicObjectStaticField == "41"); 278 279 check(otherProtectedClassProtectedBooleanStaticField == true); 280 check(otherProtectedClassProtectedByteStaticField == 42); 281 check(otherProtectedClassProtectedCharStaticField == 43); 282 check(otherProtectedClassProtectedShortStaticField == 44); 283 check(otherProtectedClassProtectedIntStaticField == 45); 284 check(otherProtectedClassProtectedLongStaticField == 46); 285 check(otherProtectedClassProtectedFloatStaticField == 47.0f); 286 check(otherProtectedClassProtectedDoubleStaticField == 48.0); 287 check(otherProtectedClassProtectedObjectStaticField == "49"); 288 289 // check(otherProtectedClassPrivateBooleanStaticField == true); 290 // check(otherProtectedClassPrivateByteStaticField == 50); 291 // check(otherProtectedClassPrivateCharStaticField == 51); 292 // check(otherProtectedClassPrivateShortStaticField == 52); 293 // check(otherProtectedClassPrivateIntStaticField == 53); 294 // check(otherProtectedClassPrivateLongStaticField == 54); 295 // check(otherProtectedClassPrivateFloatStaticField == 55.0f); 296 // check(otherProtectedClassPrivateDoubleStaticField == 56.0); 297 // check(otherProtectedClassPrivateObjectStaticField == "57"); 298 299 // check(otherProtectedClassPackageBooleanStaticField == true); 300 // check(otherProtectedClassPackageByteStaticField == 58); 301 // check(otherProtectedClassPackageCharStaticField == 59); 302 // check(otherProtectedClassPackageShortStaticField == 60); 303 // check(otherProtectedClassPackageIntStaticField == 61); 304 // check(otherProtectedClassPackageLongStaticField == 62); 305 // check(otherProtectedClassPackageFloatStaticField == 63.0f); 306 // check(otherProtectedClassPackageDoubleStaticField == 64.0); 307 // check(otherProtectedClassPackageObjectStaticField == "65"); 308 309 check(otherPublicClassPublicBooleanInstanceField == true); 310 check(otherPublicClassPublicByteInstanceField == -2); 311 check(otherPublicClassPublicCharInstanceField == (char)-3); 312 check(otherPublicClassPublicShortInstanceField == -4); 313 check(otherPublicClassPublicIntInstanceField == -5); 314 check(otherPublicClassPublicLongInstanceField == -6); 315 check(otherPublicClassPublicFloatInstanceField == -7.0f); 316 check(otherPublicClassPublicDoubleInstanceField == -8.0); 317 check(otherPublicClassPublicObjectInstanceField == "-9"); 318 319 check(otherPublicClassProtectedBooleanInstanceField == true); 320 check(otherPublicClassProtectedByteInstanceField == -10); 321 check(otherPublicClassProtectedCharInstanceField == (char)-11); 322 check(otherPublicClassProtectedShortInstanceField == -12); 323 check(otherPublicClassProtectedIntInstanceField == -13); 324 check(otherPublicClassProtectedLongInstanceField == -14); 325 check(otherPublicClassProtectedFloatInstanceField == -15.0f); 326 check(otherPublicClassProtectedDoubleInstanceField == -16.0); 327 check(otherPublicClassProtectedObjectInstanceField == "-17"); 328 329 // check(otherPublicClassPrivateBooleanInstanceField == true); 330 // check(otherPublicClassPrivateByteInstanceField == -18); 331 // check(otherPublicClassPrivateCharInstanceField == (char)-19); 332 // check(otherPublicClassPrivateShortInstanceField == -20); 333 // check(otherPublicClassPrivateIntInstanceField == -21); 334 // check(otherPublicClassPrivateLongInstanceField == -22); 335 // check(otherPublicClassPrivateFloatInstanceField == -23.0f); 336 // check(otherPublicClassPrivateDoubleInstanceField == -24.0); 337 // check(otherPublicClassPrivateObjectInstanceField == "-25"); 338 339 // check(otherPublicClassPackageBooleanInstanceField == true); 340 // check(otherPublicClassPackageByteInstanceField == -26); 341 // check(otherPublicClassPackageCharInstanceField == (char)-27); 342 // check(otherPublicClassPackageShortInstanceField == -28); 343 // check(otherPublicClassPackageIntInstanceField == -29); 344 // check(otherPublicClassPackageLongInstanceField == -30); 345 // check(otherPublicClassPackageFloatInstanceField == -31.0f); 346 // check(otherPublicClassPackageDoubleInstanceField == -32.0); 347 // check(otherPublicClassPackageObjectInstanceField == "-33"); 348 349 check(otherPublicClassPublicBooleanStaticField == true); 350 check(otherPublicClassPublicByteStaticField == -34); 351 check(otherPublicClassPublicCharStaticField == (char)-35); 352 check(otherPublicClassPublicShortStaticField == -36); 353 check(otherPublicClassPublicIntStaticField == -37); 354 check(otherPublicClassPublicLongStaticField == -38); 355 check(otherPublicClassPublicFloatStaticField == -39.0f); 356 check(otherPublicClassPublicDoubleStaticField == -40.0); 357 check(otherPublicClassPublicObjectStaticField == "-41"); 358 359 check(otherPublicClassProtectedBooleanStaticField == true); 360 check(otherPublicClassProtectedByteStaticField == -42); 361 check(otherPublicClassProtectedCharStaticField == (char)-43); 362 check(otherPublicClassProtectedShortStaticField == -44); 363 check(otherPublicClassProtectedIntStaticField == -45); 364 check(otherPublicClassProtectedLongStaticField == -46); 365 check(otherPublicClassProtectedFloatStaticField == -47.0f); 366 check(otherPublicClassProtectedDoubleStaticField == -48.0); 367 check(otherPublicClassProtectedObjectStaticField == "-49"); 368 369 // check(otherPublicClassPrivateBooleanStaticField == true); 370 // check(otherPublicClassPrivateByteStaticField == -50); 371 // check(otherPublicClassPrivateCharStaticField == (char)-51); 372 // check(otherPublicClassPrivateShortStaticField == -52); 373 // check(otherPublicClassPrivateIntStaticField == -53); 374 // check(otherPublicClassPrivateLongStaticField == -54); 375 // check(otherPublicClassPrivateFloatStaticField == -55.0f); 376 // check(otherPublicClassPrivateDoubleStaticField == -56.0); 377 // check(otherPublicClassPrivateObjectStaticField == "-57"); 378 379 // check(otherPublicClassPackageBooleanStaticField == true); 380 // check(otherPublicClassPackageByteStaticField == -58); 381 // check(otherPublicClassPackageCharStaticField == (char)-59); 382 // check(otherPublicClassPackageShortStaticField == -60); 383 // check(otherPublicClassPackageIntStaticField == -61); 384 // check(otherPublicClassPackageLongStaticField == -62); 385 // check(otherPublicClassPackageFloatStaticField == -63.0f); 386 // check(otherPublicClassPackageDoubleStaticField == -64.0); 387 // check(otherPublicClassPackageObjectStaticField == "-65"); 388 389 SamePackage s = new SamePackage(); 390 check(s.samePackagePublicBooleanInstanceField == true); 391 check(s.samePackagePublicByteInstanceField == 2); 392 check(s.samePackagePublicCharInstanceField == 3); 393 check(s.samePackagePublicShortInstanceField == 4); 394 check(s.samePackagePublicIntInstanceField == 5); 395 check(s.samePackagePublicLongInstanceField == 6); 396 check(s.samePackagePublicFloatInstanceField == 7.0f); 397 check(s.samePackagePublicDoubleInstanceField == 8.0); 398 check(s.samePackagePublicObjectInstanceField == "9"); 399 400 check(s.samePackageProtectedBooleanInstanceField == true); 401 check(s.samePackageProtectedByteInstanceField == 10); 402 check(s.samePackageProtectedCharInstanceField == 11); 403 check(s.samePackageProtectedShortInstanceField == 12); 404 check(s.samePackageProtectedIntInstanceField == 13); 405 check(s.samePackageProtectedLongInstanceField == 14); 406 check(s.samePackageProtectedFloatInstanceField == 15.0f); 407 check(s.samePackageProtectedDoubleInstanceField == 16.0); 408 check(s.samePackageProtectedObjectInstanceField == "17"); 409 410 // check(s.samePackagePrivateBooleanInstanceField == true); 411 // check(s.samePackagePrivateByteInstanceField == 18); 412 // check(s.samePackagePrivateCharInstanceField == 19); 413 // check(s.samePackagePrivateShortInstanceField == 20); 414 // check(s.samePackagePrivateIntInstanceField == 21); 415 // check(s.samePackagePrivateLongInstanceField == 22); 416 // check(s.samePackagePrivateFloatInstanceField == 23.0f); 417 // check(s.samePackagePrivateDoubleInstanceField == 24.0); 418 // check(s.samePackagePrivateObjectInstanceField == "25"); 419 420 check(s.samePackagePackageBooleanInstanceField == true); 421 check(s.samePackagePackageByteInstanceField == 26); 422 check(s.samePackagePackageCharInstanceField == 27); 423 check(s.samePackagePackageShortInstanceField == 28); 424 check(s.samePackagePackageIntInstanceField == 29); 425 check(s.samePackagePackageLongInstanceField == 30); 426 check(s.samePackagePackageFloatInstanceField == 31.0f); 427 check(s.samePackagePackageDoubleInstanceField == 32.0); 428 check(s.samePackagePackageObjectInstanceField == "33"); 429 430 check(SamePackage.samePackagePublicBooleanStaticField == true); 431 check(SamePackage.samePackagePublicByteStaticField == 34); 432 check(SamePackage.samePackagePublicCharStaticField == 35); 433 check(SamePackage.samePackagePublicShortStaticField == 36); 434 check(SamePackage.samePackagePublicIntStaticField == 37); 435 check(SamePackage.samePackagePublicLongStaticField == 38); 436 check(SamePackage.samePackagePublicFloatStaticField == 39.0f); 437 check(SamePackage.samePackagePublicDoubleStaticField == 40.0); 438 check(SamePackage.samePackagePublicObjectStaticField == "41"); 439 440 check(SamePackage.samePackageProtectedBooleanStaticField == true); 441 check(SamePackage.samePackageProtectedByteStaticField == 42); 442 check(SamePackage.samePackageProtectedCharStaticField == 43); 443 check(SamePackage.samePackageProtectedShortStaticField == 44); 444 check(SamePackage.samePackageProtectedIntStaticField == 45); 445 check(SamePackage.samePackageProtectedLongStaticField == 46); 446 check(SamePackage.samePackageProtectedFloatStaticField == 47.0f); 447 check(SamePackage.samePackageProtectedDoubleStaticField == 48.0); 448 check(SamePackage.samePackageProtectedObjectStaticField == "49"); 449 450 // check(SamePackage.samePackagePrivateBooleanStaticField == true); 451 // check(SamePackage.samePackagePrivateByteStaticField == 50); 452 // check(SamePackage.samePackagePrivateCharStaticField == 51); 453 // check(SamePackage.samePackagePrivateShortStaticField == 52); 454 // check(SamePackage.samePackagePrivateIntStaticField == 53); 455 // check(SamePackage.samePackagePrivateLongStaticField == 54); 456 // check(SamePackage.samePackagePrivateFloatStaticField == 55.0f); 457 // check(SamePackage.samePackagePrivateDoubleStaticField == 56.0); 458 // check(SamePackage.samePackagePrivateObjectStaticField == "57"); 459 460 check(SamePackage.samePackagePackageBooleanStaticField == true); 461 check(SamePackage.samePackagePackageByteStaticField == 58); 462 check(SamePackage.samePackagePackageCharStaticField == 59); 463 check(SamePackage.samePackagePackageShortStaticField == 60); 464 check(SamePackage.samePackagePackageIntStaticField == 61); 465 check(SamePackage.samePackagePackageLongStaticField == 62); 466 check(SamePackage.samePackagePackageFloatStaticField == 63.0f); 467 check(SamePackage.samePackagePackageDoubleStaticField == 64.0); 468 check(SamePackage.samePackagePackageObjectStaticField == "65"); 469 } 470 compatibleTypes(char srcType, char dstType)471 private static boolean compatibleTypes(char srcType, char dstType) { 472 switch (dstType) { 473 case 'Z': 474 case 'C': 475 case 'B': 476 return srcType == dstType; 477 case 'S': 478 return srcType == 'B' || srcType == 'S'; 479 case 'I': 480 return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I'; 481 case 'J': 482 return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' || 483 srcType == 'J'; 484 case 'F': 485 return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' || 486 srcType == 'J' || srcType == 'F'; 487 case 'D': 488 return srcType == 'B' || srcType == 'C' || srcType == 'S' || srcType == 'I' || 489 srcType == 'J' || srcType == 'F' || srcType == 'D'; 490 case 'L': 491 return true; 492 default: 493 throw new Error("Unexpected type char " + dstType); 494 } 495 } 496 doReflectionTests()497 public void doReflectionTests() { 498 String typeChars = "ZBCSIJFDL"; 499 String fieldNameForTypeChar[] = { 500 "Boolean", 501 "Byte", 502 "Char", 503 "Short", 504 "Int", 505 "Long", 506 "Float", 507 "Double", 508 "Object" 509 }; 510 511 Main localInst = new Main(); 512 SamePackage samePkgInst = new SamePackage(); 513 PublicClass otherPkgInst = new PublicClass(); 514 Object plainObj = new Object(); 515 516 for (int round = 0; round < 3; round++) { 517 Object validInst; 518 Field[] fields; 519 Method[] methods; 520 boolean same_package = false; 521 boolean protected_class = false; 522 switch (round) { 523 case 0: 524 validInst = new SamePackage(); 525 fields = SamePackage.class.getDeclaredFields(); 526 check(fields.length == 72); 527 methods = SamePackage.class.getDeclaredMethods(); 528 check(methods.length == 4); 529 same_package = true; 530 break; 531 case 1: 532 validInst = new PublicClass(); 533 fields = PublicClass.class.getDeclaredFields(); 534 check(fields.length == 72); 535 methods = PublicClass.class.getDeclaredMethods(); 536 check(methods.length == 4); 537 break; 538 default: 539 validInst = new PublicClass(); 540 fields = PublicClass.class.getSuperclass().getDeclaredFields(); 541 check(fields.length == 72); 542 methods = PublicClass.class.getSuperclass().getDeclaredMethods(); 543 check(methods.length == 4); 544 protected_class = true; 545 break; 546 } 547 for (Field f : fields) { 548 char typeChar = '?'; 549 for (int i = 0; i < fieldNameForTypeChar.length; i++) { 550 if (f.getName().contains(fieldNameForTypeChar[i])) { 551 typeChar = typeChars.charAt(i); 552 break; 553 } 554 } 555 // Check access or lack of to field. 556 Class<?> subClassAccessExceptionClass = null; 557 if ((f.getName().contains("Private") || 558 (!same_package && f.getName().contains("Package")) || 559 (!same_package && f.getName().contains("Protected"))) && 560 !(protected_class && f.getName().contains("Public"))) { 561 subClassAccessExceptionClass = IllegalAccessException.class; 562 } 563 Class<?> mainClassAccessExceptionClass = null; 564 if ((f.getName().contains("Private") || 565 (!same_package && f.getName().contains("Package")) || 566 (!same_package && f.getName().contains("Protected"))) && 567 !(protected_class && f.getName().contains("Public"))) { 568 mainClassAccessExceptionClass = IllegalAccessException.class; 569 } 570 571 this.getValue(f, validInst, typeChar, subClassAccessExceptionClass); 572 localInst.getValue(f, validInst, typeChar, mainClassAccessExceptionClass); 573 574 // Check things that can get beyond the IllegalAccessException. 575 if (subClassAccessExceptionClass == null) { 576 // Check NPE. 577 Class<?> npeClass = null; 578 if (!f.getName().contains("Static")) { 579 npeClass = NullPointerException.class; 580 } 581 582 this.getValue(f, null, typeChar, npeClass); 583 if (mainClassAccessExceptionClass == null) { 584 localInst.getValue(f, null, typeChar, npeClass); 585 } 586 587 // Check access of wrong field type for valid instance. 588 for (int i = 0; i < typeChars.length(); i++) { 589 char otherChar = typeChars.charAt(i); 590 Class<?> illArgClass = compatibleTypes(typeChar, otherChar) ? 591 null : IllegalArgumentException.class; 592 this.getValue(f, validInst, otherChar, illArgClass); 593 if (mainClassAccessExceptionClass == null) { 594 localInst.getValue(f, validInst, otherChar, illArgClass); 595 } 596 } 597 598 if (!f.getName().contains("Static")) { 599 // Wrong object. 600 this.getValue(f, plainObj, typeChar, IllegalArgumentException.class); 601 if (mainClassAccessExceptionClass == null) { 602 localInst.getValue(f, plainObj, typeChar, IllegalArgumentException.class); 603 } 604 } 605 } 606 } 607 608 for (Method m : methods) { 609 Class<?> subClassAccessExceptionClass = null; 610 if (m.getName().contains("Private") || 611 (!same_package && m.getName().contains("Package")) || 612 (!same_package && m.getName().contains("Protected"))) { 613 subClassAccessExceptionClass = IllegalAccessException.class; 614 } 615 this.invoke(m, validInst, subClassAccessExceptionClass); 616 } 617 } 618 System.out.println("good"); 619 } 620 621 /* 622 * [this is a clone of Main.getValue() -- the class issuing the 623 * reflection call is significant] 624 */ getValue(Field field, Object obj, char type, Class expectedException)625 public Object getValue(Field field, Object obj, char type, 626 Class expectedException) { 627 Object result = null; 628 try { 629 switch (type) { 630 case 'Z': 631 result = field.getBoolean(obj); 632 break; 633 case 'B': 634 result = field.getByte(obj); 635 break; 636 case 'S': 637 result = field.getShort(obj); 638 break; 639 case 'C': 640 result = field.getChar(obj); 641 break; 642 case 'I': 643 result = field.getInt(obj); 644 break; 645 case 'J': 646 result = field.getLong(obj); 647 break; 648 case 'F': 649 result = field.getFloat(obj); 650 break; 651 case 'D': 652 result = field.getDouble(obj); 653 break; 654 case 'L': 655 result = field.get(obj); 656 break; 657 default: 658 throw new RuntimeException("bad type '" + type + "'"); 659 } 660 661 /* success; expected? */ 662 if (expectedException != null) { 663 System.err.println("ERROR: call succeeded for field " + field + 664 " with a read of type '" + type + 665 "', was expecting " + expectedException); 666 Thread.dumpStack(); 667 } 668 } catch (Exception ex) { 669 if (expectedException == null) { 670 System.err.println("ERROR: call failed unexpectedly: " 671 + ex.getClass()); 672 ex.printStackTrace(); 673 } else { 674 if (!expectedException.equals(ex.getClass())) { 675 System.err.println("ERROR: incorrect exception: wanted " 676 + expectedException.getName() + ", got " 677 + ex.getClass()); 678 ex.printStackTrace(); 679 } 680 } 681 } 682 683 return result; 684 } 685 invoke(Method method, Object obj, Class expectedException)686 public Object invoke(Method method, Object obj, Class expectedException) { 687 Object result = null; 688 try { 689 result = method.invoke(obj); 690 /* success; expected? */ 691 if (expectedException != null) { 692 System.err.println("ERROR: call succeeded for method " + method + "', was expecting " + 693 expectedException); 694 Thread.dumpStack(); 695 } 696 } catch (Exception ex) { 697 if (expectedException == null) { 698 System.err.println("ERROR: call failed unexpectedly: " + ex.getClass()); 699 ex.printStackTrace(); 700 } else { 701 if (!expectedException.equals(ex.getClass())) { 702 System.err.println("ERROR: incorrect exception: wanted " + expectedException.getName() + 703 ", got " + ex.getClass()); 704 ex.printStackTrace(); 705 } 706 } 707 } 708 return result; 709 } 710 } 711