1 /* 2 * Copyright (C) 2016 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 package libcore.java.lang.reflect.annotations; 18 19 import junit.framework.TestCase; 20 21 import java.lang.annotation.Annotation; 22 import java.lang.reflect.Constructor; 23 import java.lang.reflect.Executable; 24 import java.lang.reflect.Method; 25 import java.lang.reflect.Parameter; 26 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationA; 27 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationB; 28 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationC; 29 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.AnnotationD; 30 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.Container; 31 import libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.Repeated; 32 33 import static libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.EXPECT_EMPTY; 34 import static libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.assertGetDeclaredAnnotation; 35 import static libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.assertIsAnnotationPresent; 36 import static libcore.java.lang.reflect.annotations.AnnotatedElementTestSupport.checkAnnotatedElementPresentMethods; 37 38 /** 39 * Tests for the {@link java.lang.reflect.AnnotatedElement} methods from the {@link Parameter} 40 * objects obtained from both {@link Constructor} and {@link Method}. 41 */ 42 public class AnnotatedElementParameterTest extends TestCase { 43 44 private static class MethodClass { methodWithoutAnnotatedParameters(String parameter1, String parameter2)45 public void methodWithoutAnnotatedParameters(String parameter1, String parameter2) {} 46 methodWithAnnotatedParameters(@nnotationB @nnotationD String parameter1, @AnnotationC @AnnotationD String parameter2)47 public void methodWithAnnotatedParameters(@AnnotationB @AnnotationD String parameter1, 48 @AnnotationC @AnnotationD String parameter2) {} 49 } 50 testMethodParameterAnnotations()51 public void testMethodParameterAnnotations() throws Exception { 52 Class<?> c = MethodClass.class; 53 { 54 Parameter[] parameters = c.getDeclaredMethod( 55 "methodWithoutAnnotatedParameters", String.class, String.class).getParameters(); 56 Parameter parameter0 = parameters[0]; 57 checkAnnotatedElementPresentMethods(parameter0); 58 59 Parameter parameter1 = parameters[1]; 60 checkAnnotatedElementPresentMethods(parameter1); 61 } 62 { 63 Parameter[] parameters = c.getDeclaredMethod( 64 "methodWithAnnotatedParameters", String.class, String.class).getParameters(); 65 66 Parameter parameter0 = parameters[0]; 67 checkAnnotatedElementPresentMethods(parameter0, AnnotationB.class, AnnotationD.class); 68 69 Parameter parameter1 = parameters[1]; 70 checkAnnotatedElementPresentMethods(parameter1, AnnotationC.class, AnnotationD.class); 71 } 72 } 73 74 private static class ConstructorClass { 75 // No annotations. ConstructorClass(Integer parameter1, Integer parameter2)76 public ConstructorClass(Integer parameter1, Integer parameter2) {} 77 78 // Annotations. ConstructorClass(@nnotationB @nnotationD String parameter1, @AnnotationC @AnnotationD String parameter2)79 public ConstructorClass(@AnnotationB @AnnotationD String parameter1, 80 @AnnotationC @AnnotationD String parameter2) {} 81 } 82 testConstructorParameterAnnotations()83 public void testConstructorParameterAnnotations() throws Exception { 84 Class<?> c = ConstructorClass.class; 85 { 86 Parameter[] parameters = 87 c.getDeclaredConstructor(Integer.class, Integer.class).getParameters(); 88 Parameter parameter0 = parameters[0]; 89 checkAnnotatedElementPresentMethods(parameter0); 90 91 Parameter parameter1 = parameters[1]; 92 checkAnnotatedElementPresentMethods(parameter1); 93 } 94 { 95 Parameter[] parameters = 96 c.getDeclaredConstructor(String.class, String.class).getParameters(); 97 98 Parameter parameter0 = parameters[0]; 99 checkAnnotatedElementPresentMethods(parameter0, AnnotationB.class, AnnotationD.class); 100 101 Parameter parameter1 = parameters[1]; 102 checkAnnotatedElementPresentMethods(parameter1, AnnotationC.class, AnnotationD.class); 103 } 104 } 105 106 private static class AnnotatedMethodClass { noAnnotation(String p0)107 void noAnnotation(String p0) {} 108 multipleAnnotationOddity( @epeated1) @ontainer{@Repeated(2), @Repeated(3)}) String p0)109 void multipleAnnotationOddity( 110 @Repeated(1) @Container({@Repeated(2), @Repeated(3)}) String p0) {} 111 multipleAnnotationExplicitSingle(@ontainer{@Repeated(1)}) String p0)112 void multipleAnnotationExplicitSingle(@Container({@Repeated(1)}) String p0) {} 113 multipleAnnotation(@epeated1) @epeated2) String p0)114 void multipleAnnotation(@Repeated(1) @Repeated(2) String p0) {} 115 singleAnnotation(@epeated1) String p0)116 void singleAnnotation(@Repeated(1) String p0) {} 117 staticSingleAnnotation(@epeated1) String p0)118 static void staticSingleAnnotation(@Repeated(1) String p0) {} 119 getMethodWithoutAnnotations()120 static Method getMethodWithoutAnnotations() throws Exception { 121 return AnnotatedMethodClass.class.getDeclaredMethod("noAnnotation", String.class); 122 } 123 getMethodMultipleAnnotationOddity()124 static Method getMethodMultipleAnnotationOddity() throws Exception { 125 return AnnotatedMethodClass.class.getDeclaredMethod( 126 "multipleAnnotationOddity", String.class); 127 } 128 getMethodMultipleAnnotationExplicitSingle()129 static Method getMethodMultipleAnnotationExplicitSingle() throws Exception { 130 return AnnotatedMethodClass.class.getDeclaredMethod( 131 "multipleAnnotationExplicitSingle", String.class); 132 } 133 getMethodMultipleAnnotation()134 static Method getMethodMultipleAnnotation() throws Exception { 135 return AnnotatedMethodClass.class.getDeclaredMethod("multipleAnnotation", String.class); 136 } 137 getMethodSingleAnnotation()138 static Method getMethodSingleAnnotation() throws Exception { 139 return AnnotatedMethodClass.class.getDeclaredMethod("singleAnnotation", String.class); 140 } 141 getMethodStaticSingleAnnotation()142 static Method getMethodStaticSingleAnnotation() throws Exception { 143 return AnnotatedMethodClass.class.getDeclaredMethod("staticSingleAnnotation", 144 String.class); 145 } 146 } 147 148 private static abstract class AnnotatedMethodAbstractClass { abstractSingleAnnotation(@epeated1) String p0)149 abstract void abstractSingleAnnotation(@Repeated(1) String p0); 150 getMethodAbstractSingleAnnotation()151 static Method getMethodAbstractSingleAnnotation() throws Exception { 152 return AnnotatedMethodAbstractClass.class.getDeclaredMethod( 153 "abstractSingleAnnotation", String.class); 154 } 155 } 156 157 // Tests for isAnnotationPresent and getDeclaredAnnotation. testMethodDeclaredAnnotation_repeated()158 public void testMethodDeclaredAnnotation_repeated() throws Exception { 159 Class<? extends Annotation> repeated = Repeated.class; 160 checkParameter0DeclaredAnnotation( 161 AnnotatedMethodClass.getMethodWithoutAnnotations(), 162 repeated, null); 163 checkParameter0DeclaredAnnotation( 164 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 165 repeated, "@Repeated(1)"); 166 checkParameter0DeclaredAnnotation( 167 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 168 repeated, null); 169 checkParameter0DeclaredAnnotation( 170 AnnotatedMethodClass.getMethodMultipleAnnotation(), 171 repeated, null); 172 checkParameter0DeclaredAnnotation( 173 AnnotatedMethodClass.getMethodSingleAnnotation(), 174 repeated, "@Repeated(1)"); 175 checkParameter0DeclaredAnnotation( 176 AnnotatedMethodClass.getMethodStaticSingleAnnotation(), 177 repeated, "@Repeated(1)"); 178 checkParameter0DeclaredAnnotation( 179 AnnotatedMethodAbstractClass.getMethodAbstractSingleAnnotation(), 180 repeated, "@Repeated(1)"); 181 182 Class<? extends Annotation> container = Container.class; 183 checkParameter0DeclaredAnnotation( 184 AnnotatedMethodClass.getMethodWithoutAnnotations(), 185 container, null); 186 checkParameter0DeclaredAnnotation( 187 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 188 container, "@Container({@Repeated(2), @Repeated(3)})"); 189 checkParameter0DeclaredAnnotation( 190 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 191 container, "@Container({@Repeated(1)})"); 192 checkParameter0DeclaredAnnotation( 193 AnnotatedMethodClass.getMethodMultipleAnnotation(), 194 container, "@Container({@Repeated(1), @Repeated(2)})"); 195 checkParameter0DeclaredAnnotation( 196 AnnotatedMethodClass.getMethodSingleAnnotation(), 197 container, null); 198 } 199 200 private static class AnnotatedConstructorClass { AnnotatedConstructorClass(Boolean p0)201 public AnnotatedConstructorClass(Boolean p0) {} 202 AnnotatedConstructorClass( @epeated1) @ontainer{@Repeated(2), @Repeated(3)}) Long p0)203 public AnnotatedConstructorClass( 204 @Repeated(1) @Container({@Repeated(2), @Repeated(3)}) Long p0) {} 205 AnnotatedConstructorClass(@ontainer{@Repeated(1)}) Double p0)206 public AnnotatedConstructorClass(@Container({@Repeated(1)}) Double p0) {} 207 AnnotatedConstructorClass(@epeated1) @epeated2) Integer p0)208 public AnnotatedConstructorClass(@Repeated(1) @Repeated(2) Integer p0) {} 209 AnnotatedConstructorClass(@epeated1) String p0)210 public AnnotatedConstructorClass(@Repeated(1) String p0) {} 211 getConstructorWithoutAnnotations()212 static Constructor<?> getConstructorWithoutAnnotations() throws Exception { 213 return AnnotatedConstructorClass.class.getDeclaredConstructor(Boolean.class); 214 } 215 getConstructorMultipleAnnotationOddity()216 static Constructor<?> getConstructorMultipleAnnotationOddity() throws Exception { 217 return AnnotatedConstructorClass.class.getDeclaredConstructor(Long.class); 218 } 219 getConstructorMultipleAnnotationExplicitSingle()220 static Constructor<?> getConstructorMultipleAnnotationExplicitSingle() 221 throws Exception { 222 return AnnotatedConstructorClass.class.getDeclaredConstructor(Double.class); 223 } 224 getConstructorSingleAnnotation()225 static Constructor<?> getConstructorSingleAnnotation() throws Exception { 226 return AnnotatedConstructorClass.class.getDeclaredConstructor(String.class); 227 } 228 getConstructorMultipleAnnotation()229 static Constructor<?> getConstructorMultipleAnnotation() throws Exception { 230 return AnnotatedConstructorClass.class.getDeclaredConstructor(Integer.class); 231 } 232 } 233 234 // Tests for isAnnotationPresent and getDeclaredAnnotation. testConstructorDeclaredAnnotation_repeated()235 public void testConstructorDeclaredAnnotation_repeated() throws Exception { 236 Class<? extends Annotation> repeated = Repeated.class; 237 checkParameter0DeclaredAnnotation( 238 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 239 repeated, null); 240 checkParameter0DeclaredAnnotation( 241 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 242 repeated, "@Repeated(1)"); 243 checkParameter0DeclaredAnnotation( 244 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 245 repeated, null); 246 checkParameter0DeclaredAnnotation( 247 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 248 repeated, null); 249 checkParameter0DeclaredAnnotation( 250 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 251 repeated, "@Repeated(1)"); 252 253 Class<? extends Annotation> container = Container.class; 254 checkParameter0DeclaredAnnotation( 255 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 256 container, null); 257 checkParameter0DeclaredAnnotation( 258 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 259 container, "@Container({@Repeated(2), @Repeated(3)})"); 260 checkParameter0DeclaredAnnotation( 261 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 262 container, "@Container({@Repeated(1)})"); 263 checkParameter0DeclaredAnnotation( 264 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 265 container, "@Container({@Repeated(1), @Repeated(2)})"); 266 checkParameter0DeclaredAnnotation( 267 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 268 container, null); 269 } 270 checkParameter0DeclaredAnnotation( Executable executable, Class<? extends Annotation> annotationType, String expectedAnnotationString)271 private static void checkParameter0DeclaredAnnotation( 272 Executable executable, Class<? extends Annotation> annotationType, 273 String expectedAnnotationString) throws Exception { 274 Parameter parameter = executable.getParameters()[0]; 275 276 // isAnnotationPresent 277 assertIsAnnotationPresent(parameter, annotationType, expectedAnnotationString != null); 278 279 // getDeclaredAnnotation 280 assertGetDeclaredAnnotation(parameter, annotationType, expectedAnnotationString); 281 } 282 testMethodGetDeclaredAnnotationsByType_repeated()283 public void testMethodGetDeclaredAnnotationsByType_repeated() throws Exception { 284 Class<? extends Annotation> repeated = Repeated.class; 285 checkParameter0GetDeclaredAnnotationsByType( 286 AnnotatedMethodClass.getMethodWithoutAnnotations(), 287 repeated, EXPECT_EMPTY); 288 checkParameter0GetDeclaredAnnotationsByType( 289 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 290 repeated, "@Repeated(1)", "@Repeated(2)", "@Repeated(3)"); 291 checkParameter0GetDeclaredAnnotationsByType( 292 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 293 repeated, "@Repeated(1)"); 294 checkParameter0GetDeclaredAnnotationsByType( 295 AnnotatedMethodClass.getMethodMultipleAnnotation(), 296 repeated, "@Repeated(1)", "@Repeated(2)"); 297 checkParameter0GetDeclaredAnnotationsByType( 298 AnnotatedMethodClass.getMethodSingleAnnotation(), 299 repeated, "@Repeated(1)"); 300 301 Class<? extends Annotation> container = Container.class; 302 checkParameter0GetDeclaredAnnotationsByType( 303 AnnotatedMethodClass.getMethodWithoutAnnotations(), 304 container, EXPECT_EMPTY); 305 checkParameter0GetDeclaredAnnotationsByType( 306 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 307 container, "@Container({@Repeated(2), @Repeated(3)})"); 308 checkParameter0GetDeclaredAnnotationsByType( 309 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 310 container, "@Container({@Repeated(1)})"); 311 checkParameter0GetDeclaredAnnotationsByType( 312 AnnotatedMethodClass.getMethodMultipleAnnotation(), 313 container, "@Container({@Repeated(1), @Repeated(2)})"); 314 checkParameter0GetDeclaredAnnotationsByType( 315 AnnotatedMethodClass.getMethodSingleAnnotation(), 316 container, EXPECT_EMPTY); 317 } 318 testConstructorGetDeclaredAnnotationsByType_repeated()319 public void testConstructorGetDeclaredAnnotationsByType_repeated() throws Exception { 320 Class<? extends Annotation> repeated = Repeated.class; 321 checkParameter0GetDeclaredAnnotationsByType( 322 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 323 repeated, EXPECT_EMPTY); 324 checkParameter0GetDeclaredAnnotationsByType( 325 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 326 repeated, "@Repeated(1)", "@Repeated(2)", "@Repeated(3)"); 327 checkParameter0GetDeclaredAnnotationsByType( 328 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 329 repeated, "@Repeated(1)"); 330 checkParameter0GetDeclaredAnnotationsByType( 331 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 332 repeated, "@Repeated(1)", "@Repeated(2)"); 333 checkParameter0GetDeclaredAnnotationsByType( 334 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 335 repeated, "@Repeated(1)"); 336 337 Class<? extends Annotation> container = Container.class; 338 checkParameter0GetDeclaredAnnotationsByType( 339 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 340 container, EXPECT_EMPTY); 341 checkParameter0GetDeclaredAnnotationsByType( 342 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 343 container, "@Container({@Repeated(2), @Repeated(3)})"); 344 checkParameter0GetDeclaredAnnotationsByType( 345 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 346 container, "@Container({@Repeated(1)})"); 347 checkParameter0GetDeclaredAnnotationsByType( 348 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 349 container, "@Container({@Repeated(1), @Repeated(2)})"); 350 checkParameter0GetDeclaredAnnotationsByType( 351 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 352 container, EXPECT_EMPTY); 353 } 354 checkParameter0GetDeclaredAnnotationsByType( Executable executable, Class<? extends Annotation> annotationType, String... expectedAnnotationStrings)355 private static void checkParameter0GetDeclaredAnnotationsByType( 356 Executable executable, Class<? extends Annotation> annotationType, 357 String... expectedAnnotationStrings) throws Exception { 358 Parameter parameter = executable.getParameters()[0]; 359 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 360 parameter, annotationType, expectedAnnotationStrings); 361 } 362 testMethodGetAnnotationsByType_repeated()363 public void testMethodGetAnnotationsByType_repeated() throws Exception { 364 Class<? extends Annotation> repeated = Repeated.class; 365 checkParameter0GetAnnotationsByType( 366 AnnotatedMethodClass.getMethodWithoutAnnotations(), 367 repeated, EXPECT_EMPTY); 368 checkParameter0GetAnnotationsByType( 369 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 370 repeated, "@Repeated(1)", "@Repeated(2)", "@Repeated(3)"); 371 checkParameter0GetAnnotationsByType( 372 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 373 repeated, "@Repeated(1)"); 374 checkParameter0GetAnnotationsByType( 375 AnnotatedMethodClass.getMethodMultipleAnnotation(), 376 repeated, "@Repeated(1)", "@Repeated(2)"); 377 checkParameter0GetAnnotationsByType( 378 AnnotatedMethodClass.getMethodSingleAnnotation(), 379 repeated, "@Repeated(1)"); 380 381 Class<? extends Annotation> container = Container.class; 382 checkParameter0GetAnnotationsByType( 383 AnnotatedMethodClass.getMethodWithoutAnnotations(), 384 container, EXPECT_EMPTY); 385 checkParameter0GetAnnotationsByType( 386 AnnotatedMethodClass.getMethodMultipleAnnotationOddity(), 387 container, "@Container({@Repeated(2), @Repeated(3)})"); 388 checkParameter0GetAnnotationsByType( 389 AnnotatedMethodClass.getMethodMultipleAnnotationExplicitSingle(), 390 container, "@Container({@Repeated(1)})"); 391 checkParameter0GetAnnotationsByType( 392 AnnotatedMethodClass.getMethodMultipleAnnotation(), 393 container, "@Container({@Repeated(1), @Repeated(2)})"); 394 checkParameter0GetAnnotationsByType( 395 AnnotatedMethodClass.getMethodSingleAnnotation(), 396 container, EXPECT_EMPTY); 397 } 398 testConstructorGetAnnotationsByType_repeated()399 public void testConstructorGetAnnotationsByType_repeated() throws Exception { 400 Class<? extends Annotation> repeated = Repeated.class; 401 checkParameter0GetAnnotationsByType( 402 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 403 repeated, EXPECT_EMPTY); 404 checkParameter0GetAnnotationsByType( 405 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 406 repeated, "@Repeated(1)", "@Repeated(2)", "@Repeated(3)"); 407 checkParameter0GetAnnotationsByType( 408 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 409 repeated, "@Repeated(1)"); 410 checkParameter0GetAnnotationsByType( 411 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 412 repeated, "@Repeated(1)", "@Repeated(2)"); 413 checkParameter0GetAnnotationsByType( 414 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 415 repeated, "@Repeated(1)"); 416 417 Class<? extends Annotation> container = Container.class; 418 checkParameter0GetAnnotationsByType( 419 AnnotatedConstructorClass.getConstructorWithoutAnnotations(), 420 container, EXPECT_EMPTY); 421 checkParameter0GetAnnotationsByType( 422 AnnotatedConstructorClass.getConstructorMultipleAnnotationOddity(), 423 container, "@Container({@Repeated(2), @Repeated(3)})"); 424 checkParameter0GetAnnotationsByType( 425 AnnotatedConstructorClass.getConstructorMultipleAnnotationExplicitSingle(), 426 container, "@Container({@Repeated(1)})"); 427 checkParameter0GetAnnotationsByType( 428 AnnotatedConstructorClass.getConstructorMultipleAnnotation(), 429 container, "@Container({@Repeated(1), @Repeated(2)})"); 430 checkParameter0GetAnnotationsByType( 431 AnnotatedConstructorClass.getConstructorSingleAnnotation(), 432 container, EXPECT_EMPTY); 433 } 434 checkParameter0GetAnnotationsByType( Executable executable, Class<? extends Annotation> annotationType, String... expectedAnnotationStrings)435 private static void checkParameter0GetAnnotationsByType( 436 Executable executable, Class<? extends Annotation> annotationType, 437 String... expectedAnnotationStrings) throws Exception { 438 Parameter parameter = executable.getParameters()[0]; 439 AnnotatedElementTestSupport.assertGetAnnotationsByType( 440 parameter, annotationType, expectedAnnotationStrings); 441 } 442 443 /** 444 * As an inner class the constructor will actually have two parameters: the first, referencing 445 * the enclosing object, is inserted by the compiler. 446 */ 447 class InnerClass { InnerClass(@nnotationA String p1)448 InnerClass(@AnnotationA String p1) {} 449 } 450 451 /** Special case testing for a compiler-generated constructor parameter. JLS 8.8.1, JLS 13.1. */ testImplicitConstructorParameters_innerClass()452 public void testImplicitConstructorParameters_innerClass() throws Exception { 453 Constructor<InnerClass> constructor = 454 InnerClass.class.getDeclaredConstructor( 455 AnnotatedElementParameterTest.class, String.class); 456 Parameter[] parameters = constructor.getParameters(); 457 458 // The parameter annotation code behaves as if there are two parameters. 459 460 // The compiler-generated constructor should have no annotations. 461 Parameter parameter0 = parameters[0]; 462 AnnotatedElementTestSupport.assertGetAnnotationsByType( 463 parameter0, AnnotationA.class, new String[0]); 464 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 465 parameter0, AnnotationA.class, new String[0]); 466 AnnotatedElementTestSupport.assertGetDeclaredAnnotation( 467 parameter0, AnnotationA.class, null); 468 AnnotatedElementTestSupport.assertIsAnnotationPresent(parameter0, AnnotationA.class, false); 469 470 // The annotation should remain on the correct parameter. 471 Parameter parameter1 = parameters[1]; 472 AnnotatedElementTestSupport.assertGetAnnotationsByType( 473 parameter1, AnnotationA.class, new String[] {"@AnnotationA"}); 474 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 475 parameter1, AnnotationA.class, new String[] {"@AnnotationA"}); 476 AnnotatedElementTestSupport.assertGetDeclaredAnnotation( 477 parameter1, AnnotationA.class, "@AnnotationA"); 478 AnnotatedElementTestSupport.assertIsAnnotationPresent( 479 parameter1, AnnotationA.class, true); 480 } 481 482 static abstract class AnonymousBaseClass { AnonymousBaseClass(@nnotationA String p1)483 public AnonymousBaseClass(@AnnotationA String p1) {} 484 } 485 486 /** Special case testing for a compiler-generated constructor parameter. JLS 13.1 */ testImplicitConstructorParameters_anonymousClass()487 public void testImplicitConstructorParameters_anonymousClass() throws Exception { 488 /* 489 * As an anonymous class the constructor will actually have two parameters: the first, 490 * referencing the enclosing object, is inserted by the compiler. 491 */ 492 AnonymousBaseClass anonymousClassInstance = new AnonymousBaseClass("p1") {}; 493 494 Constructor<? extends AnonymousBaseClass> constructor = 495 anonymousClassInstance.getClass().getDeclaredConstructor( 496 AnnotatedElementParameterTest.class, String.class); 497 Parameter[] parameters = constructor.getParameters(); 498 assertEquals(2, parameters.length); 499 500 // The parameter annotation code behaves as if there are two parameters. 501 502 // This is the synthetic parameter. 503 Parameter parameter0 = parameters[0]; 504 AnnotatedElementTestSupport.assertGetAnnotationsByType( 505 parameter0, AnnotationA.class, new String[0]); 506 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 507 parameter0, AnnotationA.class, new String[0]); 508 AnnotatedElementTestSupport.assertGetDeclaredAnnotation( 509 parameter0, AnnotationA.class, null); 510 AnnotatedElementTestSupport.assertIsAnnotationPresent(parameter0, AnnotationA.class, false); 511 512 // There's no annotation since we cannot annotate the parameter on the anonymous class. 513 Parameter parameter1 = parameters[1]; 514 AnnotatedElementTestSupport.assertGetAnnotationsByType( 515 parameter1, AnnotationA.class, new String[0]); 516 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 517 parameter1, AnnotationA.class, new String[0]); 518 AnnotatedElementTestSupport.assertGetDeclaredAnnotation( 519 parameter1, AnnotationA.class, null); 520 AnnotatedElementTestSupport.assertIsAnnotationPresent(parameter1, AnnotationA.class, false); 521 } 522 523 /** 524 * A static inner / nested member class will not have synthetic parameters and should behave 525 * like a top-level class. 526 */ 527 static class StaticInnerClass { StaticInnerClass(@nnotationA String p1)528 StaticInnerClass(@AnnotationA String p1) {} 529 } 530 531 /** Special case testing for a compiler-generated constructor parameter. */ testImplicitConstructorParameters_staticInnerClass()532 public void testImplicitConstructorParameters_staticInnerClass() throws Exception { 533 Constructor<StaticInnerClass> constructor = 534 StaticInnerClass.class.getDeclaredConstructor(String.class); 535 Parameter[] parameters = constructor.getParameters(); 536 assertEquals(1, parameters.length); 537 538 Parameter parameter0 = parameters[0]; 539 AnnotatedElementTestSupport.assertGetAnnotationsByType( 540 parameter0, AnnotationA.class, new String[] {"@AnnotationA"}); 541 AnnotatedElementTestSupport.assertGetDeclaredAnnotationsByType( 542 parameter0, AnnotationA.class, new String[] {"@AnnotationA"}); 543 AnnotatedElementTestSupport.assertGetDeclaredAnnotation( 544 parameter0, AnnotationA.class, "@AnnotationA"); 545 AnnotatedElementTestSupport.assertIsAnnotationPresent( 546 parameter0, AnnotationA.class, true); 547 } 548 } 549