1 /* 2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8004698 8007073 8022343 8054304 8057804 8058595 27 * @summary Unit test for type annotations 28 */ 29 30 import java.util.*; 31 import java.lang.annotation.*; 32 import java.lang.reflect.*; 33 import java.io.Serializable; 34 35 public class TypeAnnotationReflection { main(String[] args)36 public static void main(String[] args) throws Exception { 37 testSuper(); 38 testInterfaces(); 39 testReturnType(); 40 testNested(); 41 testArray(); 42 testRunException(); 43 testClassTypeVarBounds(); 44 testMethodTypeVarBounds(); 45 testFields(); 46 testClassTypeVar(); 47 testMethodTypeVar(); 48 testParameterizedType(); 49 testNestedParameterizedType(); 50 testWildcardType(); 51 testParameterTypes(); 52 testParameterType(); 53 } 54 check(boolean b)55 private static void check(boolean b) { 56 if (!b) 57 throw new RuntimeException(); 58 } 59 testSuper()60 private static void testSuper() throws Exception { 61 check(Object.class.getAnnotatedSuperclass() == null); 62 check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0); 63 64 AnnotatedType a; 65 a = TestClassArray.class.getAnnotatedSuperclass(); 66 Annotation[] annos = a.getAnnotations(); 67 check(annos.length == 2); 68 check(annos[0].annotationType().equals(TypeAnno.class)); 69 check(annos[1].annotationType().equals(TypeAnno2.class)); 70 check(((TypeAnno)annos[0]).value().equals("extends")); 71 check(((TypeAnno2)annos[1]).value().equals("extends2")); 72 } 73 testInterfaces()74 private static void testInterfaces() throws Exception { 75 AnnotatedType[] as; 76 as = TestClassArray.class.getAnnotatedInterfaces(); 77 check(as.length == 3); 78 check(as[1].getAnnotations().length == 0); 79 80 Annotation[] annos; 81 annos = as[0].getAnnotations(); 82 check(annos.length == 2); 83 check(annos[0].annotationType().equals(TypeAnno.class)); 84 check(annos[1].annotationType().equals(TypeAnno2.class)); 85 check(((TypeAnno)annos[0]).value().equals("implements serializable")); 86 check(((TypeAnno2)annos[1]).value().equals("implements2 serializable")); 87 88 annos = as[2].getAnnotations(); 89 check(annos.length == 2); 90 check(annos[0].annotationType().equals(TypeAnno.class)); 91 check(annos[1].annotationType().equals(TypeAnno2.class)); 92 check(((TypeAnno)annos[0]).value().equals("implements cloneable")); 93 check(((TypeAnno2)annos[1]).value().equals("implements2 cloneable")); 94 } 95 testReturnType()96 private static void testReturnType() throws Exception { 97 Method m = TestClassArray.class.getDeclaredMethod("foo", (Class<?>[])null); 98 Annotation[] annos = m.getAnnotatedReturnType().getAnnotations(); 99 check(annos.length == 1); 100 check(annos[0].annotationType().equals(TypeAnno.class)); 101 check(((TypeAnno)annos[0]).value().equals("return1")); 102 } 103 testNested()104 private static void testNested() throws Exception { 105 Method m = TestClassNested.class.getDeclaredMethod("foo", (Class<?>[])null); 106 Annotation[] annos = m.getAnnotatedReturnType().getAnnotations(); 107 check(annos.length == 1); 108 check(annos[0].annotationType().equals(TypeAnno.class)); 109 check(((TypeAnno)annos[0]).value().equals("array")); 110 111 AnnotatedType t = m.getAnnotatedReturnType(); 112 t = ((AnnotatedArrayType)t).getAnnotatedGenericComponentType(); 113 annos = t.getAnnotations(); 114 check(annos.length == 1); 115 check(annos[0].annotationType().equals(TypeAnno.class)); 116 check(((TypeAnno)annos[0]).value().equals("Inner")); 117 } 118 testArray()119 private static void testArray() throws Exception { 120 Method m = TestClassArray.class.getDeclaredMethod("foo", (Class<?>[])null); 121 AnnotatedArrayType t = (AnnotatedArrayType) m.getAnnotatedReturnType(); 122 Annotation[] annos = t.getAnnotations(); 123 check(annos.length == 1); 124 check(annos[0].annotationType().equals(TypeAnno.class)); 125 check(((TypeAnno)annos[0]).value().equals("return1")); 126 127 t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType(); 128 annos = t.getAnnotations(); 129 check(annos.length == 0); 130 131 t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType(); 132 annos = t.getAnnotations(); 133 check(annos.length == 1); 134 check(annos[0].annotationType().equals(TypeAnno.class)); 135 check(((TypeAnno)annos[0]).value().equals("return3")); 136 137 AnnotatedType tt = t.getAnnotatedGenericComponentType(); 138 check(!(tt instanceof AnnotatedArrayType)); 139 annos = tt.getAnnotations(); 140 check(annos.length == 1); 141 check(annos[0].annotationType().equals(TypeAnno.class)); 142 check(((TypeAnno)annos[0]).value().equals("return4")); 143 } 144 testRunException()145 private static void testRunException() throws Exception { 146 Method m = TestClassException.class.getDeclaredMethod("foo", (Class<?>[])null); 147 AnnotatedType[] ts = m.getAnnotatedExceptionTypes(); 148 check(ts.length == 3); 149 150 AnnotatedType t; 151 Annotation[] annos; 152 t = ts[0]; 153 annos = t.getAnnotations(); 154 check(annos.length == 2); 155 check(annos[0].annotationType().equals(TypeAnno.class)); 156 check(annos[1].annotationType().equals(TypeAnno2.class)); 157 check(((TypeAnno)annos[0]).value().equals("RE")); 158 check(((TypeAnno2)annos[1]).value().equals("RE2")); 159 160 t = ts[1]; 161 annos = t.getAnnotations(); 162 check(annos.length == 0); 163 164 t = ts[2]; 165 annos = t.getAnnotations(); 166 check(annos.length == 1); 167 check(annos[0].annotationType().equals(TypeAnno.class)); 168 check(((TypeAnno)annos[0]).value().equals("AIOOBE")); 169 } 170 testClassTypeVarBounds()171 private static void testClassTypeVarBounds() throws Exception { 172 Method m = TestClassTypeVarAndField.class.getDeclaredMethod("foo", (Class<?>[])null); 173 AnnotatedType ret = m.getAnnotatedReturnType(); 174 Annotation[] annos = ret.getAnnotations(); 175 check(annos.length == 2); 176 177 AnnotatedType[] annotatedBounds = ((AnnotatedTypeVariable)ret).getAnnotatedBounds(); 178 check(annotatedBounds.length == 2); 179 180 annos = annotatedBounds[0].getAnnotations(); 181 check(annos.length == 1); 182 check(annos[0].annotationType().equals(TypeAnno.class)); 183 check(((TypeAnno)annos[0]).value().equals("Object1")); 184 185 annos = annotatedBounds[1].getAnnotations(); 186 check(annos.length == 2); 187 check(annos[0].annotationType().equals(TypeAnno.class)); 188 check(annos[1].annotationType().equals(TypeAnno2.class)); 189 check(((TypeAnno)annos[0]).value().equals("Runnable1")); 190 check(((TypeAnno2)annos[1]).value().equals("Runnable2")); 191 } 192 testMethodTypeVarBounds()193 private static void testMethodTypeVarBounds() throws Exception { 194 Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class<?>[])null); 195 AnnotatedType ret2 = m2.getAnnotatedReturnType(); 196 AnnotatedType[] annotatedBounds2 = ((AnnotatedTypeVariable)ret2).getAnnotatedBounds(); 197 check(annotatedBounds2.length == 1); 198 199 Annotation[] annos = annotatedBounds2[0].getAnnotations(); 200 check(annos.length == 1); 201 check(annos[0].annotationType().equals(TypeAnno.class)); 202 check(((TypeAnno)annos[0]).value().equals("M Runnable")); 203 204 // Check that AnnotatedTypeVariable.getAnnotatedBounds() returns jlO for a naked 205 // type variable (i.e no bounds, no annotations) 206 Method m4 = TestClassTypeVarAndField.class.getDeclaredMethod("foo4", (Class<?>[])null); 207 AnnotatedType ret4 = m4.getAnnotatedReturnType(); 208 AnnotatedType[] annotatedBounds4 = ((AnnotatedTypeVariable)ret4).getAnnotatedBounds(); 209 check(annotatedBounds4.length == 1); 210 211 annos = annotatedBounds4[0].getAnnotations(); 212 check(annos.length == 0); 213 check(annotatedBounds4[0].getType().equals(Object.class)); 214 } 215 testFields()216 private static void testFields() throws Exception { 217 Field f1 = TestClassTypeVarAndField.class.getDeclaredField("field1"); 218 AnnotatedType at; 219 Annotation[] annos; 220 221 at = f1.getAnnotatedType(); 222 annos = at.getAnnotations(); 223 check(annos.length == 2); 224 check(annos[0].annotationType().equals(TypeAnno.class)); 225 check(annos[1].annotationType().equals(TypeAnno2.class)); 226 check(((TypeAnno)annos[0]).value().equals("T1 field")); 227 check(((TypeAnno2)annos[1]).value().equals("T2 field")); 228 229 Field f2 = TestClassTypeVarAndField.class.getDeclaredField("field2"); 230 at = f2.getAnnotatedType(); 231 annos = at.getAnnotations(); 232 check(annos.length == 0); 233 234 Field f3 = TestClassTypeVarAndField.class.getDeclaredField("field3"); 235 at = f3.getAnnotatedType(); 236 annos = at.getAnnotations(); 237 check(annos.length == 1); 238 check(annos[0].annotationType().equals(TypeAnno.class)); 239 check(((TypeAnno)annos[0]).value().equals("Object field")); 240 } 241 testClassTypeVar()242 private static void testClassTypeVar() throws Exception { 243 TypeVariable[] typeVars = TestClassTypeVarAndField.class.getTypeParameters(); 244 Annotation[] annos; 245 check(typeVars.length == 3); 246 247 // First TypeVar 248 AnnotatedType[] annotatedBounds = typeVars[0].getAnnotatedBounds(); 249 check(annotatedBounds.length == 2); 250 251 annos = annotatedBounds[0].getAnnotations(); 252 check(annos.length == 1); 253 check(annos[0].annotationType().equals(TypeAnno.class)); 254 check(((TypeAnno)annos[0]).value().equals("Object1")); 255 256 annos = annotatedBounds[1].getAnnotations(); 257 check(annos.length == 2); 258 check(annos[0].annotationType().equals(TypeAnno.class)); 259 check(annos[1].annotationType().equals(TypeAnno2.class)); 260 check(((TypeAnno)annos[0]).value().equals("Runnable1")); 261 check(((TypeAnno2)annos[1]).value().equals("Runnable2")); 262 263 // second TypeVar regular anno 264 Annotation[] regularAnnos = typeVars[1].getAnnotations(); 265 check(regularAnnos.length == 1); 266 check(typeVars[1].getAnnotation(TypeAnno.class).value().equals("EE")); 267 268 // second TypeVar 269 annotatedBounds = typeVars[1].getAnnotatedBounds(); 270 check(annotatedBounds.length == 1); 271 272 annos = annotatedBounds[0].getAnnotations(); 273 check(annos.length == 1); 274 check(annos[0].annotationType().equals(TypeAnno2.class)); 275 check(((TypeAnno2)annos[0]).value().equals("EEBound")); 276 277 // third Typevar V declared without explicit bounds should see jlO as its bound. 278 annotatedBounds = typeVars[2].getAnnotatedBounds(); 279 check(annotatedBounds.length == 1); 280 281 annos = annotatedBounds[0].getAnnotations(); 282 check(annos.length == 0); 283 check(annotatedBounds[0].getType().equals(Object.class)); 284 } 285 testMethodTypeVar()286 private static void testMethodTypeVar() throws Exception { 287 Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class<?>[])null); 288 TypeVariable[] t = m2.getTypeParameters(); 289 check(t.length == 1); 290 Annotation[] annos = t[0].getAnnotations(); 291 check(annos.length == 0); 292 293 AnnotatedType[] annotatedBounds2 = t[0].getAnnotatedBounds(); 294 check(annotatedBounds2.length == 1); 295 296 annos = annotatedBounds2[0].getAnnotations(); 297 check(annos.length == 1); 298 check(annos[0].annotationType().equals(TypeAnno.class)); 299 check(((TypeAnno)annos[0]).value().equals("M Runnable")); 300 301 // Second method 302 m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo3", (Class<?>[])null); 303 t = m2.getTypeParameters(); 304 check(t.length == 2); 305 annos = t[0].getAnnotations(); 306 check(annos.length == 1); 307 check(annos[0].annotationType().equals(TypeAnno.class)); 308 check(((TypeAnno)annos[0]).value().equals("K")); 309 310 annotatedBounds2 = t[0].getAnnotatedBounds(); 311 check(annotatedBounds2.length == 1); 312 313 annos = annotatedBounds2[0].getAnnotations(); 314 check(annos.length == 0); 315 316 // for the naked type variable L of foo3, we should see jlO as its bound. 317 annotatedBounds2 = t[1].getAnnotatedBounds(); 318 check(annotatedBounds2.length == 1); 319 check(annotatedBounds2[0].getType().equals(Object.class)); 320 321 annos = annotatedBounds2[0].getAnnotations(); 322 check(annos.length == 0); 323 } 324 testParameterizedType()325 private static void testParameterizedType() { 326 // Base 327 AnnotatedType[] as; 328 as = TestParameterizedType.class.getAnnotatedInterfaces(); 329 check(as.length == 1); 330 check(as[0].getAnnotations().length == 1); 331 check(as[0].getAnnotation(TypeAnno.class).value().equals("M")); 332 333 Annotation[] annos; 334 as = ((AnnotatedParameterizedType)as[0]).getAnnotatedActualTypeArguments(); 335 check(as.length == 2); 336 annos = as[0].getAnnotations(); 337 check(annos.length == 1); 338 check(as[0].getAnnotation(TypeAnno.class).value().equals("S")); 339 check(as[0].getAnnotation(TypeAnno2.class) == null); 340 341 annos = as[1].getAnnotations(); 342 check(annos.length == 2); 343 check(((TypeAnno)annos[0]).value().equals("I")); 344 check(as[1].getAnnotation(TypeAnno2.class).value().equals("I2")); 345 } 346 testNestedParameterizedType()347 private static void testNestedParameterizedType() throws Exception { 348 Method m = TestParameterizedType.class.getDeclaredMethod("foo2", (Class<?>[])null); 349 AnnotatedType ret = m.getAnnotatedReturnType(); 350 Annotation[] annos; 351 annos = ret.getAnnotations(); 352 check(annos.length == 1); 353 check(((TypeAnno)annos[0]).value().equals("I")); 354 355 AnnotatedType[] args = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments(); 356 check(args.length == 1); 357 annos = args[0].getAnnotations(); 358 check(annos.length == 2); 359 check(((TypeAnno)annos[0]).value().equals("I1")); 360 check(args[0].getAnnotation(TypeAnno2.class).value().equals("I2")); 361 362 // check type args 363 Field f = TestParameterizedType.class.getDeclaredField("theField"); 364 AnnotatedParameterizedType fType = (AnnotatedParameterizedType)f.getAnnotatedType(); 365 args = fType.getAnnotatedActualTypeArguments(); 366 check(args.length == 1); 367 annos = args[0].getAnnotations(); 368 check(annos.length == 1); 369 check(((TypeAnno2)annos[0]).value().equals("Map Arg")); 370 check(args[0].getAnnotation(TypeAnno2.class).value().equals("Map Arg")); 371 372 // check outer type type args 373 fType = (AnnotatedParameterizedType)fType.getAnnotatedOwnerType(); 374 args = fType.getAnnotatedActualTypeArguments(); 375 check(args.length == 1); 376 annos = args[0].getAnnotations(); 377 check(annos.length == 1); 378 check(((TypeAnno2)annos[0]).value().equals("String Arg")); 379 check(args[0].getAnnotation(TypeAnno2.class).value().equals("String Arg")); 380 381 // check outer type normal type annotations 382 annos = fType.getAnnotations(); 383 check(annos.length == 1); 384 check(((TypeAnno)annos[0]).value().equals("FieldOuter")); 385 check(fType.getAnnotation(TypeAnno.class).value().equals("FieldOuter")); 386 } 387 testWildcardType()388 private static void testWildcardType() throws Exception { 389 Method m = TestWildcardType.class.getDeclaredMethod("foo", (Class<?>[])null); 390 AnnotatedType ret = m.getAnnotatedReturnType(); 391 AnnotatedType[] t; 392 t = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments(); 393 check(t.length == 1); 394 ret = t[0]; 395 396 Field f = TestWildcardType.class.getDeclaredField("f1"); 397 AnnotatedWildcardType w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f 398 .getAnnotatedType()).getAnnotatedActualTypeArguments()[0]; 399 t = w.getAnnotatedLowerBounds(); 400 check(t.length == 0); 401 t = w.getAnnotatedUpperBounds(); 402 check(t.length == 1); 403 Annotation[] annos; 404 annos = t[0].getAnnotations(); 405 check(annos.length == 1); 406 check(((TypeAnno)annos[0]).value().equals("2")); 407 408 f = TestWildcardType.class.getDeclaredField("f2"); 409 w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f 410 .getAnnotatedType()).getAnnotatedActualTypeArguments()[0]; 411 t = w.getAnnotatedUpperBounds(); 412 check(t.length == 1); 413 check(t[0].getType().equals(Object.class)); 414 annos = t[0].getAnnotations(); 415 check(annos.length == 0); 416 t = w.getAnnotatedLowerBounds(); 417 check(t.length == 1); 418 419 // for an unbounded wildcard, we should see jlO as its upperbound and null type as its lower bound. 420 f = TestWildcardType.class.getDeclaredField("f3"); 421 w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f 422 .getAnnotatedType()).getAnnotatedActualTypeArguments()[0]; 423 t = w.getAnnotatedUpperBounds(); 424 check(t.length == 1); 425 check(t[0].getType().equals(Object.class)); 426 annos = t[0].getAnnotations(); 427 check(annos.length == 0); 428 t = w.getAnnotatedLowerBounds(); 429 check(t.length == 0); 430 } 431 testParameterTypes()432 private static void testParameterTypes() throws Exception { 433 // NO PARAMS 434 Method m = Params.class.getDeclaredMethod("noParams", (Class<?>[])null); 435 AnnotatedType[] t = m.getAnnotatedParameterTypes(); 436 check(t.length == 0); 437 438 // ONLY ANNOTATED PARAM TYPES 439 Class[] argsArr = {String.class, String.class, String.class}; 440 m = Params.class.getDeclaredMethod("onlyAnnotated", (Class<?>[])argsArr); 441 t = m.getAnnotatedParameterTypes(); 442 check(t.length == 3); 443 444 check(t[0].getAnnotations().length == 1); 445 check(t[0].getAnnotation(TypeAnno.class) != null); 446 check(t[0].getAnnotationsByType(TypeAnno.class)[0].value().equals("1")); 447 448 check(t[1].getAnnotations().length == 1); 449 check(t[1].getAnnotation(TypeAnno.class) != null); 450 check(t[1].getAnnotationsByType(TypeAnno.class)[0].value().equals("2")); 451 452 check(t[2].getAnnotations().length == 2); 453 check(t[2].getAnnotations()[0].annotationType().equals(TypeAnno.class)); 454 check(t[2].getAnnotation(TypeAnno.class) != null); 455 check(t[2].getAnnotation(TypeAnno2.class) != null); 456 check(t[2].getAnnotationsByType(TypeAnno.class)[0].value().equals("3a")); 457 check(t[2].getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b")); 458 459 // MIXED ANNOTATED PARAM TYPES 460 m = Params.class.getDeclaredMethod("mixed", (Class<?>[])argsArr); 461 t = m.getAnnotatedParameterTypes(); 462 check(t.length == 3); 463 464 check(t[0].getAnnotations().length == 1); 465 check(t[0].getAnnotation(TypeAnno.class) != null); 466 check(t[0].getAnnotationsByType(TypeAnno.class)[0].value().equals("1")); 467 468 check(t[1].getAnnotations().length == 0); 469 check(t[1].getAnnotation(TypeAnno.class) == null); 470 check(t[1].getAnnotation(TypeAnno2.class) == null); 471 472 check(t[2].getAnnotations().length == 2); 473 check(t[2].getAnnotations()[0].annotationType().equals(TypeAnno.class)); 474 check(t[2].getAnnotation(TypeAnno.class) != null); 475 check(t[2].getAnnotation(TypeAnno2.class) != null); 476 check(t[2].getAnnotationsByType(TypeAnno.class)[0].value().equals("3a")); 477 check(t[2].getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b")); 478 479 // NO ANNOTATED PARAM TYPES 480 m = Params.class.getDeclaredMethod("unAnnotated", (Class<?>[])argsArr); 481 t = m.getAnnotatedParameterTypes(); 482 check(t.length == 3); 483 484 check(t[0].getAnnotations().length == 0); 485 check(t[0].getAnnotation(TypeAnno.class) == null); 486 check(t[0].getAnnotation(TypeAnno2.class) == null); 487 488 check(t[1].getAnnotations().length == 0); 489 check(t[1].getAnnotation(TypeAnno.class) == null); 490 check(t[1].getAnnotation(TypeAnno2.class) == null); 491 492 check(t[2].getAnnotations().length == 0); 493 check(t[2].getAnnotation(TypeAnno.class) == null); 494 check(t[2].getAnnotation(TypeAnno2.class) == null); 495 } 496 testParameterType()497 private static void testParameterType() throws Exception { 498 // NO PARAMS 499 Method m = Params.class.getDeclaredMethod("noParams", (Class<?>[])null); 500 Parameter[] p = m.getParameters(); 501 check(p.length == 0); 502 503 // ONLY ANNOTATED PARAM TYPES 504 Class[] argsArr = {String.class, String.class, String.class}; 505 m = Params.class.getDeclaredMethod("onlyAnnotated", (Class<?>[])argsArr); 506 p = m.getParameters(); 507 check(p.length == 3); 508 AnnotatedType t0 = p[0].getAnnotatedType(); 509 AnnotatedType t1 = p[1].getAnnotatedType(); 510 AnnotatedType t2 = p[2].getAnnotatedType(); 511 512 check(t0.getAnnotations().length == 1); 513 check(t0.getAnnotation(TypeAnno.class) != null); 514 check(t0.getAnnotationsByType(TypeAnno.class)[0].value().equals("1")); 515 516 check(t1.getAnnotations().length == 1); 517 check(t1.getAnnotation(TypeAnno.class) != null); 518 check(t1.getAnnotationsByType(TypeAnno.class)[0].value().equals("2")); 519 520 check(t2.getAnnotations().length == 2); 521 check(t2.getAnnotations()[0].annotationType().equals(TypeAnno.class)); 522 check(t2.getAnnotation(TypeAnno.class) != null); 523 check(t2.getAnnotation(TypeAnno2.class) != null); 524 check(t2.getAnnotationsByType(TypeAnno.class)[0].value().equals("3a")); 525 check(t2.getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b")); 526 527 // MIXED ANNOTATED PARAM TYPES 528 m = Params.class.getDeclaredMethod("mixed", (Class<?>[])argsArr); 529 p = m.getParameters(); 530 check(p.length == 3); 531 532 t0 = p[0].getAnnotatedType(); 533 t1 = p[1].getAnnotatedType(); 534 t2 = p[2].getAnnotatedType(); 535 536 check(t0.getAnnotations().length == 1); 537 check(t0.getAnnotation(TypeAnno.class) != null); 538 check(t0.getAnnotationsByType(TypeAnno.class)[0].value().equals("1")); 539 540 check(t1.getAnnotations().length == 0); 541 check(t1.getAnnotation(TypeAnno.class) == null); 542 check(t1.getAnnotation(TypeAnno2.class) == null); 543 544 check(t2.getAnnotations().length == 2); 545 check(t2.getAnnotations()[0].annotationType().equals(TypeAnno.class)); 546 check(t2.getAnnotation(TypeAnno.class) != null); 547 check(t2.getAnnotation(TypeAnno2.class) != null); 548 check(t2.getAnnotationsByType(TypeAnno.class)[0].value().equals("3a")); 549 check(t2.getAnnotationsByType(TypeAnno2.class)[0].value().equals("3b")); 550 551 // NO ANNOTATED PARAM TYPES 552 m = Params.class.getDeclaredMethod("unAnnotated", (Class<?>[])argsArr); 553 p = m.getParameters(); 554 check(p.length == 3); 555 556 t0 = p[0].getAnnotatedType(); 557 t1 = p[1].getAnnotatedType(); 558 t2 = p[2].getAnnotatedType(); 559 560 check(t0.getAnnotations().length == 0); 561 check(t0.getAnnotation(TypeAnno.class) == null); 562 check(t0.getAnnotation(TypeAnno2.class) == null); 563 564 check(t1.getAnnotations().length == 0); 565 check(t1.getAnnotation(TypeAnno.class) == null); 566 check(t1.getAnnotation(TypeAnno2.class) == null); 567 568 check(t2.getAnnotations().length == 0); 569 check(t2.getAnnotation(TypeAnno.class) == null); 570 check(t2.getAnnotation(TypeAnno2.class) == null); 571 } 572 } 573 574 class Params { noParams()575 public void noParams() {} onlyAnnotated(@ypeAnnoR) String s1, @TypeAnno(R) String s2, @TypeAnno(R) @TypeAnno2(R) String s3)576 public void onlyAnnotated(@TypeAnno("1") String s1, @TypeAnno("2") String s2, @TypeAnno("3a") @TypeAnno2("3b") String s3) {} mixed(@ypeAnnoR) String s1, String s2, @TypeAnno(R) @TypeAnno2(R) String s3)577 public void mixed(@TypeAnno("1") String s1, String s2, @TypeAnno("3a") @TypeAnno2("3b") String s3) {} unAnnotated(String s1, String s2, String s3)578 public void unAnnotated(String s1, String s2, String s3) {} 579 } 580 581 abstract class TestWildcardType { foo()582 public <T> List<? super T> foo() { return null;} 583 public Class<@TypeAnno("1") ? extends @TypeAnno("2") Annotation> f1; 584 public Class<@TypeAnno("3") ? super @TypeAnno("4") Annotation> f2; 585 public Class<@TypeAnno("5") ?> f3; 586 } 587 588 abstract class TestParameterizedType implements @TypeAnno("M") Map<@TypeAnno("S")String, @TypeAnno("I") @TypeAnno2("I2")Integer> { foo()589 public ParameterizedOuter<String>.ParameterizedInner<Integer> foo() {return null;} 590 public @TypeAnno("O") ParameterizedOuter<@TypeAnno("S1") @TypeAnno2("S2") String>. foo2()591 @TypeAnno("I") ParameterizedInner<@TypeAnno("I1") @TypeAnno2("I2")Integer> foo2() { 592 return null; 593 } 594 595 public @TypeAnno("FieldOuter") ParameterizedOuter<@TypeAnno2("String Arg") String>. 596 @TypeAnno("FieldInner")ParameterizedInner<@TypeAnno2("Map Arg")Map> theField; 597 } 598 599 class ParameterizedOuter <T> { 600 class ParameterizedInner <U> {} 601 } 602 603 abstract class TestClassArray extends @TypeAnno("extends") @TypeAnno2("extends2") Object 604 implements @TypeAnno("implements serializable") @TypeAnno2("implements2 serializable") Serializable, 605 Readable, 606 @TypeAnno("implements cloneable") @TypeAnno2("implements2 cloneable") Cloneable { foo()607 public @TypeAnno("return4") Object @TypeAnno("return1") [][] @TypeAnno("return3")[] foo() { return null; } 608 } 609 610 abstract class TestClassNested { foo()611 public @TypeAnno("Outer") Outer.@TypeAnno("Inner")Inner @TypeAnno("array")[] foo() { return null; } 612 } 613 614 class Outer { 615 class Inner { 616 } 617 } 618 619 abstract class TestClassException { 620 public Object foo() throws @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException, 621 NullPointerException, 622 @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException { 623 return null; 624 } 625 } 626 627 abstract class TestClassTypeVarAndField <T extends @TypeAnno("Object1") Object 628 & @TypeAnno("Runnable1") @TypeAnno2("Runnable2") Runnable, 629 @TypeAnno("EE")EE extends @TypeAnno2("EEBound") Runnable, V > { 630 @TypeAnno("T1 field") @TypeAnno2("T2 field") T field1; 631 T field2; 632 @TypeAnno("Object field") Object field3; 633 foo()634 public @TypeAnno("t1") @TypeAnno2("t2") T foo(){ return null; } foo2()635 public <M extends @TypeAnno("M Runnable") Runnable> M foo2() {return null;} foo3()636 public <@TypeAnno("K") K extends Cloneable, L> K foo3() {return null;} foo4()637 public <L> L foo4() {return null;} 638 } 639 640 @Target(ElementType.TYPE_USE) 641 @Retention(RetentionPolicy.RUNTIME) 642 @interface TypeAnno { value()643 String value(); 644 } 645 646 @Target(ElementType.TYPE_USE) 647 @Retention(RetentionPolicy.RUNTIME) 648 @interface TypeAnno2 { value()649 String value(); 650 } 651