1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.tests.java.lang; 19 20 import java.io.FileInputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.Serializable; 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 import java.lang.reflect.Constructor; 27 import java.lang.reflect.Field; 28 import java.lang.reflect.Method; 29 import java.lang.reflect.Modifier; 30 import java.net.URL; 31 import java.security.AccessController; 32 import java.security.BasicPermission; 33 import java.security.DomainCombiner; 34 import java.security.Permission; 35 import java.security.ProtectionDomain; 36 import java.security.Security; 37 import java.util.Arrays; 38 import java.util.List; 39 import java.util.TreeMap; 40 import java.util.Vector; 41 import java.util.function.Function; 42 43 public class ClassTest extends junit.framework.TestCase { 44 45 // Relative resource paths. 46 private static final String SHARP_RESOURCE_RELATIVE_NAME = "test#.properties"; 47 private static final String QUERY_RESOURCE_RELATIVE_NAME = "test?.properties"; 48 private static final String RESOURCE_RELATIVE_NAME = "test.properties"; 49 50 // Absolute resource paths. 51 private static final String ABS_PATH = 52 ClassTest.class.getPackage().getName().replace('.', '/'); 53 public static final String SHARP_RESOURCE_ABS_NAME = 54 ABS_PATH + "/" + SHARP_RESOURCE_RELATIVE_NAME; 55 public static final String QUERY_RESOURCE_ABS_NAME = 56 ABS_PATH + "/" + QUERY_RESOURCE_RELATIVE_NAME; 57 public static final String RESOURCE_ABS_NAME = ABS_PATH + "/" + RESOURCE_RELATIVE_NAME; 58 59 public static class TestClass { 60 @SuppressWarnings("unused") 61 private int privField = 1; 62 63 public int pubField = 2; 64 65 private Object cValue = null; 66 67 public Object ack = new Object(); 68 69 @SuppressWarnings("unused") privMethod()70 private int privMethod() { 71 return 1; 72 } 73 pubMethod()74 public int pubMethod() { 75 return 2; 76 } 77 cValue()78 public Object cValue() { 79 return cValue; 80 } 81 TestClass()82 public TestClass() { 83 } 84 85 @SuppressWarnings("unused") TestClass(Object o)86 private TestClass(Object o) { 87 } 88 } 89 90 public static class SubTestClass extends TestClass { 91 } 92 93 /** 94 * java.lang.Class#forName(java.lang.String) 95 */ test_forNameLjava_lang_String()96 public void test_forNameLjava_lang_String() throws Exception { 97 assertSame("Class for name failed for java.lang.Object", 98 Object.class, Class.forName("java.lang.Object")); 99 assertSame("Class for name failed for [[Ljava.lang.Object;", 100 Object[][].class, Class.forName("[[Ljava.lang.Object;")); 101 102 assertSame("Class for name failed for [I", 103 int[].class, Class.forName("[I")); 104 105 try { 106 Class.forName("int"); 107 fail(); 108 } catch (ClassNotFoundException e) { 109 } 110 111 try { 112 Class.forName("byte"); 113 fail(); 114 } catch (ClassNotFoundException e) { 115 } 116 try { 117 Class.forName("char"); 118 fail(); 119 } catch (ClassNotFoundException e) { 120 } 121 122 try { 123 Class.forName("void"); 124 fail(); 125 } catch (ClassNotFoundException e) { 126 } 127 128 try { 129 Class.forName("short"); 130 fail(); 131 } catch (ClassNotFoundException e) { 132 } 133 try { 134 Class.forName("long"); 135 fail(); 136 } catch (ClassNotFoundException e) { 137 } 138 139 try { 140 Class.forName("boolean"); 141 fail(); 142 } catch (ClassNotFoundException e) { 143 } 144 try { 145 Class.forName("float"); 146 fail(); 147 } catch (ClassNotFoundException e) { 148 } 149 try { 150 Class.forName("double"); 151 fail(); 152 } catch (ClassNotFoundException e) { 153 } 154 155 //regression test for JIRA 2162 156 try { 157 Class.forName("%"); 158 fail("should throw ClassNotFoundException."); 159 } catch (ClassNotFoundException e) { 160 } 161 162 //Regression Test for HARMONY-3332 163 String securityProviderClassName; 164 int count = 1; 165 while ((securityProviderClassName = Security 166 .getProperty("security.provider." + count++)) != null) { 167 Class.forName(securityProviderClassName); 168 } 169 } 170 171 /** 172 * java.lang.Class#getClasses() 173 */ test_getClasses()174 public void test_getClasses() { 175 assertEquals("Incorrect class array returned", 176 2, ClassTest.class.getClasses().length); 177 } 178 179 /** 180 * java.lang.Class#getClasses() 181 */ test_getClasses_subtest0()182 public void test_getClasses_subtest0() { 183 final Permission privCheckPermission = new BasicPermission("Privilege check") { 184 private static final long serialVersionUID = 1L; 185 }; 186 187 class MyCombiner implements DomainCombiner { 188 boolean combine; 189 190 public ProtectionDomain[] combine(ProtectionDomain[] executionDomains, 191 ProtectionDomain[] parentDomains) { 192 combine = true; 193 return new ProtectionDomain[0]; 194 } 195 196 private boolean recurring = false; 197 198 public boolean isPriviledged() { 199 if (recurring) { 200 return true; 201 } 202 try { 203 recurring = true; 204 combine = false; 205 try { 206 AccessController.checkPermission(privCheckPermission); 207 } catch (SecurityException e) { 208 } 209 return !combine; 210 } finally { 211 recurring = false; 212 } 213 } 214 } 215 } 216 217 /** 218 * java.lang.Class#getComponentType() 219 */ test_getComponentType()220 public void test_getComponentType() { 221 assertSame("int array does not have int component type", int.class, int[].class 222 .getComponentType()); 223 assertSame("Object array does not have Object component type", Object.class, 224 Object[].class.getComponentType()); 225 assertNull("Object has non-null component type", Object.class.getComponentType()); 226 } 227 228 /** 229 * java.lang.Class#getConstructor(java.lang.Class[]) 230 */ test_getConstructor$Ljava_lang_Class()231 public void test_getConstructor$Ljava_lang_Class() 232 throws NoSuchMethodException { 233 TestClass.class.getConstructor(new Class[0]); 234 try { 235 TestClass.class.getConstructor(Object.class); 236 fail("Found private constructor"); 237 } catch (NoSuchMethodException e) { 238 // Correct - constructor with obj is private 239 } 240 } 241 242 /** 243 * java.lang.Class#getConstructors() 244 */ test_getConstructors()245 public void test_getConstructors() throws Exception { 246 Constructor[] c = TestClass.class.getConstructors(); 247 assertEquals("Incorrect number of constructors returned", 1, c.length); 248 } 249 250 /** 251 * java.lang.Class#getDeclaredClasses() 252 */ test_getDeclaredClasses()253 public void test_getDeclaredClasses() { 254 assertEquals("Incorrect class array returned", 2, ClassTest.class.getClasses().length); 255 } 256 257 /** 258 * java.lang.Class#getDeclaredConstructor(java.lang.Class[]) 259 */ test_getDeclaredConstructor$Ljava_lang_Class()260 public void test_getDeclaredConstructor$Ljava_lang_Class() throws Exception { 261 Constructor<TestClass> c = TestClass.class.getDeclaredConstructor(new Class[0]); 262 assertNull("Incorrect constructor returned", c.newInstance().cValue()); 263 c = TestClass.class.getDeclaredConstructor(Object.class); 264 } 265 266 /** 267 * java.lang.Class#getDeclaredConstructors() 268 */ test_getDeclaredConstructors()269 public void test_getDeclaredConstructors() throws Exception { 270 Constructor[] c = TestClass.class.getDeclaredConstructors(); 271 assertEquals("Incorrect number of constructors returned", 2, c.length); 272 } 273 274 /** 275 * java.lang.Class#getDeclaredField(java.lang.String) 276 */ test_getDeclaredFieldLjava_lang_String()277 public void test_getDeclaredFieldLjava_lang_String() throws Exception { 278 Field f = TestClass.class.getDeclaredField("pubField"); 279 assertEquals("Returned incorrect field", 2, f.getInt(new TestClass())); 280 } 281 282 /** 283 * java.lang.Class#getDeclaredFields() 284 */ test_getDeclaredFields()285 public void test_getDeclaredFields() throws Exception { 286 Field[] f = TestClass.class.getDeclaredFields(); 287 assertEquals("Returned incorrect number of fields", 4, f.length); 288 f = SubTestClass.class.getDeclaredFields(); 289 // Declared fields do not include inherited 290 assertEquals("Returned incorrect number of fields", 0, f.length); 291 } 292 293 /** 294 * java.lang.Class#getDeclaredMethod(java.lang.String, 295 *java.lang.Class[]) 296 */ test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class()297 public void test_getDeclaredMethodLjava_lang_String$Ljava_lang_Class() throws Exception { 298 Method m = TestClass.class.getDeclaredMethod("pubMethod", new Class[0]); 299 assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass()))) 300 .intValue()); 301 m = TestClass.class.getDeclaredMethod("privMethod", new Class[0]); 302 } 303 304 /** 305 * java.lang.Class#getDeclaredMethods() 306 */ test_getDeclaredMethods()307 public void test_getDeclaredMethods() throws Exception { 308 Method[] m = TestClass.class.getDeclaredMethods(); 309 assertEquals("Returned incorrect number of methods", 3, m.length); 310 m = SubTestClass.class.getDeclaredMethods(); 311 assertEquals("Returned incorrect number of methods", 0, m.length); 312 } 313 314 /** 315 * java.lang.Class#getDeclaringClass() 316 */ test_getDeclaringClass()317 public void test_getDeclaringClass() { 318 assertEquals(ClassTest.class, TestClass.class.getDeclaringClass()); 319 } 320 321 /** 322 * java.lang.Class#getField(java.lang.String) 323 */ test_getFieldLjava_lang_String()324 public void test_getFieldLjava_lang_String() throws Exception { 325 Field f = TestClass.class.getField("pubField"); 326 assertEquals("Returned incorrect field", 2, f.getInt(new TestClass())); 327 try { 328 f = TestClass.class.getField("privField"); 329 fail("Private field access failed to throw exception"); 330 } catch (NoSuchFieldException e) { 331 // Correct 332 } 333 } 334 335 /** 336 * java.lang.Class#getFields() 337 */ test_getFields()338 public void test_getFields() throws Exception { 339 Field[] f = TestClass.class.getFields(); 340 assertEquals("Incorrect number of fields", 2, f.length); 341 f = SubTestClass.class.getFields(); 342 // Check inheritance of pub fields 343 assertEquals("Incorrect number of fields", 2, f.length); 344 } 345 346 /** 347 * java.lang.Class#getInterfaces() 348 */ test_getInterfaces()349 public void test_getInterfaces() { 350 Class[] interfaces; 351 List<?> interfaceList; 352 interfaces = Object.class.getInterfaces(); 353 assertEquals("Incorrect interface list for Object", 0, interfaces.length); 354 interfaceList = Arrays.asList(Vector.class.getInterfaces()); 355 assertTrue("Incorrect interface list for Vector", interfaceList 356 .contains(Cloneable.class) 357 && interfaceList.contains(Serializable.class) 358 && interfaceList.contains(List.class)); 359 } 360 361 /** 362 * java.lang.Class#getMethod(java.lang.String, java.lang.Class[]) 363 */ test_getMethodLjava_lang_String$Ljava_lang_Class()364 public void test_getMethodLjava_lang_String$Ljava_lang_Class() throws Exception { 365 Method m = TestClass.class.getMethod("pubMethod", new Class[0]); 366 assertEquals("Returned incorrect method", 2, ((Integer) (m.invoke(new TestClass()))) 367 .intValue()); 368 try { 369 m = TestClass.class.getMethod("privMethod", new Class[0]); 370 fail("Failed to throw exception accessing private method"); 371 } catch (NoSuchMethodException e) { 372 // Correct 373 return; 374 } 375 } 376 377 /** 378 * java.lang.Class#getMethods() 379 */ test_getMethods()380 public void test_getMethods() throws Exception { 381 Method[] m = TestClass.class.getMethods(); 382 assertEquals("Returned incorrect number of methods", 383 2 + Object.class.getMethods().length, m.length); 384 m = SubTestClass.class.getMethods(); 385 assertEquals("Returned incorrect number of sub-class methods", 386 2 + Object.class.getMethods().length, m.length); 387 // Number of inherited methods 388 } 389 390 private static final class PrivateClass { 391 } 392 393 /** 394 * java.lang.Class#getModifiers() 395 */ test_getModifiers()396 public void test_getModifiers() { 397 int dcm = PrivateClass.class.getModifiers(); 398 assertFalse("default class is public", Modifier.isPublic(dcm)); 399 assertFalse("default class is protected", Modifier.isProtected(dcm)); 400 assertTrue("default class is not private", Modifier.isPrivate(dcm)); 401 402 int ocm = Object.class.getModifiers(); 403 assertTrue("public class is not public", Modifier.isPublic(ocm)); 404 assertFalse("public class is protected", Modifier.isProtected(ocm)); 405 assertFalse("public class is private", Modifier.isPrivate(ocm)); 406 } 407 408 /** 409 * java.lang.Class#getName() 410 */ test_getName()411 public void test_getName() throws Exception { 412 String className = Class.forName("java.lang.Object").getName(); 413 assertNotNull(className); 414 415 assertEquals("Class getName printed wrong value", "java.lang.Object", className); 416 assertEquals("Class getName printed wrong value", "int", int.class.getName()); 417 className = Class.forName("[I").getName(); 418 assertNotNull(className); 419 assertEquals("Class getName printed wrong value", "[I", className); 420 421 className = Class.forName("[Ljava.lang.Object;").getName(); 422 assertNotNull(className); 423 424 assertEquals("Class getName printed wrong value", "[Ljava.lang.Object;", className); 425 } 426 427 /** 428 * java.lang.Class#getResource(java.lang.String) 429 */ test_getResourceLjava_lang_String()430 public void test_getResourceLjava_lang_String() { 431 final String name = "/resources/test_resource.txt"; 432 URL res = getClass().getResource(name); 433 assertNotNull(res); 434 } 435 436 /** 437 * java.lang.Class#getResourceAsStream(java.lang.String) 438 */ test_getResourceAsStreamLjava_lang_String()439 public void test_getResourceAsStreamLjava_lang_String() throws Exception { 440 final String name = "/resources/test_resource.txt"; 441 InputStream str2 = getClass().getResourceAsStream(name); 442 assertNotNull("the file " + name + " can not be found in this directory", str2); 443 444 final String nameBadURI = "org/apache/harmony/luni/tests/test_resource.txt"; 445 assertNull("the file " + nameBadURI + " should not be found in this directory", 446 getClass().getResourceAsStream(nameBadURI)); 447 448 assertTrue("Cannot read single byte", str2.read() != -1); 449 assertEquals("Cannot read multiple bytes", 5, str2.read(new byte[5])); 450 str2.close(); 451 } 452 453 /** 454 * java.lang.Class#getSuperclass() 455 */ test_getSuperclass()456 public void test_getSuperclass() { 457 assertNull("Object has a superclass???", Object.class.getSuperclass()); 458 assertSame("Normal class has bogus superclass", InputStream.class, 459 FileInputStream.class.getSuperclass()); 460 assertSame("Array class has bogus superclass", Object.class, FileInputStream[].class 461 .getSuperclass()); 462 assertNull("Base class has a superclass", int.class.getSuperclass()); 463 assertNull("Interface class has a superclass", Cloneable.class.getSuperclass()); 464 } 465 466 /** 467 * java.lang.Class#isArray() 468 */ test_isArray()469 public void test_isArray() throws ClassNotFoundException { 470 assertTrue("Non-array type claims to be.", !int.class.isArray()); 471 Class<?> clazz = null; 472 clazz = Class.forName("[I"); 473 assertTrue("int Array type claims not to be.", clazz.isArray()); 474 475 clazz = Class.forName("[Ljava.lang.Object;"); 476 assertTrue("Object Array type claims not to be.", clazz.isArray()); 477 478 clazz = Class.forName("java.lang.Object"); 479 assertTrue("Non-array Object type claims to be.", !clazz.isArray()); 480 } 481 482 /** 483 * java.lang.Class#isAssignableFrom(java.lang.Class) 484 */ test_isAssignableFromLjava_lang_Class()485 public void test_isAssignableFromLjava_lang_Class() { 486 Class<?> clazz1 = null; 487 Class<?> clazz2 = null; 488 489 clazz1 = Object.class; 490 clazz2 = Class.class; 491 assertTrue("returned false for superclass", clazz1.isAssignableFrom(clazz2)); 492 493 clazz1 = TestClass.class; 494 assertTrue("returned false for same class", clazz1.isAssignableFrom(clazz1)); 495 496 clazz1 = Runnable.class; 497 clazz2 = Thread.class; 498 assertTrue("returned false for implemented interface", clazz1.isAssignableFrom(clazz2)); 499 } 500 501 /** 502 * java.lang.Class#isInterface() 503 */ test_isInterface()504 public void test_isInterface() throws ClassNotFoundException { 505 assertTrue("Prim type claims to be interface.", !int.class.isInterface()); 506 Class<?> clazz = null; 507 clazz = Class.forName("[I"); 508 assertTrue("Prim Array type claims to be interface.", !clazz.isInterface()); 509 510 clazz = Class.forName("java.lang.Runnable"); 511 assertTrue("Interface type claims not to be interface.", clazz.isInterface()); 512 clazz = Class.forName("java.lang.Object"); 513 assertTrue("Object type claims to be interface.", !clazz.isInterface()); 514 515 clazz = Class.forName("[Ljava.lang.Object;"); 516 assertTrue("Array type claims to be interface.", !clazz.isInterface()); 517 } 518 519 /** 520 * java.lang.Class#isPrimitive() 521 */ test_isPrimitive()522 public void test_isPrimitive() { 523 assertFalse("Interface type claims to be primitive.", Runnable.class.isPrimitive()); 524 assertFalse("Object type claims to be primitive.", Object.class.isPrimitive()); 525 assertFalse("Prim Array type claims to be primitive.", int[].class.isPrimitive()); 526 assertFalse("Array type claims to be primitive.", Object[].class.isPrimitive()); 527 assertTrue("Prim type claims not to be primitive.", int.class.isPrimitive()); 528 assertFalse("Object type claims to be primitive.", Object.class.isPrimitive()); 529 } 530 531 /** 532 * java.lang.Class#newInstance() 533 */ test_newInstance()534 public void test_newInstance() throws Exception { 535 Class<?> clazz = null; 536 clazz = Class.forName("java.lang.Object"); 537 assertNotNull("new object instance was null", clazz.newInstance()); 538 539 clazz = Class.forName("java.lang.Throwable"); 540 assertSame("new Throwable instance was not a throwable", 541 clazz, clazz.newInstance().getClass()); 542 543 clazz = Class.forName("java.lang.Integer"); 544 try { 545 clazz.newInstance(); 546 fail("Exception for instantiating a newInstance with no default constructor is not thrown"); 547 } catch (InstantiationException e) { 548 // expected 549 } 550 } 551 552 // Regression Test for JIRA-2047 test_getResourceAsStream_withSharpChar()553 public void test_getResourceAsStream_withSharpChar() throws Exception { 554 // Class.getResourceAsStream() requires a leading "/" for absolute paths. 555 assertNull(getClass().getResourceAsStream(SHARP_RESOURCE_ABS_NAME)); 556 assertResourceExists("/" + SHARP_RESOURCE_ABS_NAME); 557 assertResourceExists(SHARP_RESOURCE_RELATIVE_NAME); 558 559 InputStream in = 560 this.getClass().getClassLoader().getResourceAsStream(SHARP_RESOURCE_ABS_NAME); 561 assertNotNull(in); 562 in.close(); 563 } 564 test_getResource_withSharpChar()565 public void test_getResource_withSharpChar() throws Exception { 566 // Class.getResourceAsStream() requires a leading "/" for absolute paths. 567 assertNull(getClass().getResource(SHARP_RESOURCE_ABS_NAME)); 568 URL absoluteURL = getClass().getResource("/" + SHARP_RESOURCE_ABS_NAME); 569 570 // Make sure the name has been encoded. 571 assertEquals(ABS_PATH + "/test%23.properties", 572 absoluteURL.getFile().replaceAll("^.*!/", "")); 573 574 // Make sure accessing it via an absolute and relative path produces the same result. 575 URL relativeURL = getClass().getResource(SHARP_RESOURCE_RELATIVE_NAME); 576 assertEquals(absoluteURL, relativeURL); 577 } 578 test_getResourceAsStream_withQueryChar()579 public void test_getResourceAsStream_withQueryChar() throws Exception { 580 // Class.getResourceAsStream() requires a leading "/" for absolute paths. 581 assertNull(getClass().getResourceAsStream(QUERY_RESOURCE_ABS_NAME)); 582 assertResourceExists("/" + QUERY_RESOURCE_ABS_NAME); 583 assertResourceExists(QUERY_RESOURCE_RELATIVE_NAME); 584 585 InputStream in = 586 this.getClass().getClassLoader().getResourceAsStream(QUERY_RESOURCE_ABS_NAME); 587 assertNotNull(in); 588 in.close(); 589 } 590 test_getResource_withQueryChar()591 public void test_getResource_withQueryChar() throws Exception { 592 // Class.getResourceAsStream() requires a leading "/" for absolute paths. 593 assertNull(getClass().getResource(QUERY_RESOURCE_ABS_NAME)); 594 URL absoluteURL = getClass().getResource("/" + QUERY_RESOURCE_ABS_NAME); 595 596 // Make sure the name has been encoded. 597 assertEquals(ABS_PATH + "/test%3f.properties", 598 absoluteURL.getFile().replaceAll("^.*!/", "")); 599 600 // Make sure accessing it via an absolute and relative path produces the same result. 601 URL relativeURL = getClass().getResource(QUERY_RESOURCE_RELATIVE_NAME); 602 assertEquals(absoluteURL, relativeURL); 603 } 604 test_getResourceAsStream()605 public void test_getResourceAsStream() throws Exception { 606 // Class.getResourceAsStream() requires a leading "/" for absolute paths. 607 assertNull(getClass().getResourceAsStream(RESOURCE_ABS_NAME)); 608 assertResourceExists("/" + RESOURCE_ABS_NAME); 609 assertResourceExists(RESOURCE_RELATIVE_NAME); 610 611 InputStream in = this.getClass().getClassLoader().getResourceAsStream(RESOURCE_ABS_NAME); 612 assertNotNull(in); 613 in.close(); 614 } 615 assertResourceExists(String resourceName)616 private void assertResourceExists(String resourceName) throws IOException { 617 InputStream in = getClass().getResourceAsStream(resourceName); 618 assertNotNull(in); 619 in.close(); 620 } 621 622 /* 623 * Regression test for HARMONY-2644: 624 * Load system and non-system array classes via Class.forName() 625 */ test_forName_arrays()626 public void test_forName_arrays() throws Exception { 627 Class c1 = getClass(); 628 String s = c1.getName(); 629 Class a1 = Class.forName("[L" + s + ";"); 630 Class a2 = Class.forName("[[L" + s + ";"); 631 assertSame(c1, a1.getComponentType()); 632 assertSame(a1, a2.getComponentType()); 633 Class l4 = Class.forName("[[[[[J"); 634 assertSame(long[][][][][].class, l4); 635 636 try { 637 System.out.println(Class.forName("[;")); 638 fail("1"); 639 } catch (ClassNotFoundException ok) { 640 } 641 try { 642 System.out.println(Class.forName("[[")); 643 fail("2"); 644 } catch (ClassNotFoundException ok) { 645 } 646 try { 647 System.out.println(Class.forName("[L")); 648 fail("3"); 649 } catch (ClassNotFoundException ok) { 650 } 651 try { 652 System.out.println(Class.forName("[L;")); 653 fail("4"); 654 } catch (ClassNotFoundException ok) { 655 } 656 try { 657 System.out.println(Class.forName(";")); 658 fail("5"); 659 } catch (ClassNotFoundException ok) { 660 } 661 try { 662 System.out.println(Class.forName("")); 663 fail("6"); 664 } catch (ClassNotFoundException ok) { 665 } 666 } 667 } 668