1 /* 2 * Copyright (c) 2003, 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 4891872 27 * @summary Some tests for the generic core reflection api. 28 * @author Gilad Bracha 29 * @compile TestC2.java 30 * @run main/othervm -ea TestC2 31 */ 32 33 34 import java.lang.reflect.*; 35 36 37 abstract class C0<T> { 38 39 public T ft; 40 public C0<T> fc1t; 41 public C0 fc1; 42 C0()43 public C0(){} C0(T t)44 public C0(T t) {} 45 mc1t(T t, C0<T> c1t, C0 c1)46 public abstract C0<T> mc1t(T t, C0<T> c1t, C0 c1); 47 mc1()48 public abstract C0 mc1(); 49 mt(T t)50 public abstract T mt(T t); 51 52 } 53 54 interface I1<X1, X2> extends I3 { 55 foo(X2 x2)56 X1 foo(X2 x2); 57 } 58 59 interface I2<E1, E2 extends Throwable, E3> { 60 61 bar(E3 e3)62 E1 bar(E3 e3) throws E2; 63 64 } 65 66 interface I3 { 67 68 69 } 70 71 72 abstract class C2<T1 extends C2<T1, T2, T3>, T2 extends C0<T2>, 73 T3 extends Throwable> 74 extends C0<T1> 75 implements I1<T1, T2>, I2<T1, T3, T2>, I3 76 { 77 78 public T1 ft; 79 public C0<String> fc1t; 80 public C0 fc1; 81 public int fi; 82 C2(T2 t2)83 public C2(T2 t2) {} C2(T t)84 public <T> C2(T t) {} C2(T1 t1, T2 t2, T4 t4)85 public <T1, T2, T3, T4> C2(T1 t1, T2 t2, T4 t4) {} C2()86 public C2() throws T3 {} 87 mc1t(T3 t3, C0<T> c1t, C0 c1)88 public abstract <T> C0<T> mc1t(T3 t3, C0<T> c1t, C0 c1); 89 mc1(E e)90 public abstract <E, R> C0 mc1(E e); 91 mt(T2 t)92 public abstract T1 mt(T2 t); 93 94 } 95 96 public class TestC2 { 97 98 static Class<C2> cls = C2.class; 99 100 main(String[] args)101 public static void main(String[] args) throws Throwable { 102 testSuperclass(); 103 testSuperInterfaces(); 104 testTypeParameters(); 105 testMethods(); 106 testConstructors(); 107 testFields(); 108 } 109 testSuperclass()110 static void testSuperclass() { 111 112 System.out.println("testing superclass"); 113 Type sc = cls.getGenericSuperclass(); 114 assert 115 sc instanceof ParameterizedType : 116 "Superclass of C2 should be a parameterized type"; 117 ParameterizedType psc = (ParameterizedType) sc; 118 assert 119 ((psc.getRawType() == C0.class) ) : 120 "The raw generic superclass of C2 should be C0"; 121 122 Type[] tas = psc.getActualTypeArguments(); 123 assert 124 tas.length == 1 : 125 "Superclass of C2 should have one type argument"; 126 127 Type t = tas[0]; 128 129 assert 130 t instanceof TypeVariable : 131 "Type argument to superclass of C2 should be a type variable"; 132 133 TypeVariable tv = (TypeVariable) t; 134 assert 135 tv.getName().equals("T1") : 136 "Name of type argument to superclass of C2 should be T1"; 137 Type[] bs = tv.getBounds(); 138 assert 139 bs.length == 1 : 140 "T1 has one bound (superclass)"; 141 t = bs[0]; 142 assert 143 t instanceof ParameterizedType : 144 "Bound of C0 should be a parameterized type"; 145 ParameterizedType pt = (ParameterizedType) t; 146 147 assert 148 ((pt.getRawType() == C2.class) ) : 149 "The raw bound of T1 should be C2"; 150 151 tas = pt.getActualTypeArguments(); 152 assert 153 tas.length == 3 : 154 "Bound of T1 should have three type arguments"; 155 assert 156 tas[0] instanceof TypeVariable : 157 "First argument to bound of T1 is a type variable"; 158 assert 159 tas[1] instanceof TypeVariable : 160 "Second argument to bound of T1 is a type variable"; 161 assert 162 tas[2] instanceof TypeVariable : 163 "Third argument to bound of T1 is a type variable"; 164 165 TypeVariable tv1 = (TypeVariable) tas[0]; 166 TypeVariable tv2 = (TypeVariable) tas[1]; 167 TypeVariable tv3 = (TypeVariable) tas[2]; 168 169 assert 170 tv1.getName().equals("T1"): 171 "First type arg to bound of T1 is T1"; 172 assert 173 tv2.getName().equals("T2"): 174 "Seconmd type arg to bound of T1 is T2"; 175 assert 176 tv3.getName().equals("T3"): 177 "Third type arg to bound of T1 is T3"; 178 179 180 } 181 testSuperInterfaces()182 static void testSuperInterfaces() { 183 System.out.println("testing superinterfaces"); 184 Type[] sis = cls.getGenericInterfaces(); 185 assert 186 ((sis.length == 3)): 187 "C2 should have three generic superinterfaces"; 188 189 Type t = sis[0]; 190 assert 191 t instanceof ParameterizedType : 192 "First superinterface of C2 should be a parameterized type"; 193 ParameterizedType pt = (ParameterizedType) t; 194 assert 195 pt.getRawType() == I1.class : 196 "First super interface of C2 is instantiation of I1"; 197 Type[] tas = pt.getActualTypeArguments(); 198 assert 199 tas.length == 2 : 200 "First super interface of C2 has 2 type arguments"; 201 202 t = sis[1]; 203 assert 204 t instanceof ParameterizedType : 205 "Second superinterface of C2 should be a parameterized type"; 206 pt = (ParameterizedType) t; 207 assert 208 pt.getRawType() == I2.class : 209 "Second super interface of C2 is instantiation of I2"; 210 tas = pt.getActualTypeArguments(); 211 assert 212 tas.length == 3 : 213 "Second super interface of C2 has 3 type arguments"; 214 215 t = sis[2]; 216 assert 217 t == I3.class : 218 "Third superinterface of C2 is I3"; 219 220 // Test interfaces themselves 221 222 TypeVariable[] tvs = I1.class.getTypeParameters(); 223 assert 224 tvs.length == 2 : 225 "I3 has two formal type parameters"; 226 assert 227 tvs[0].getName().equals("X1") : 228 "Name of first formal type arg of I1 is X1"; 229 assert 230 tvs[1].getName().equals("X2") : 231 "Name of second formal type arg of I1 is X2"; 232 233 assert 234 I1.class.getGenericSuperclass() == I1.class.getSuperclass() : 235 "The generic and non-generic superclasses of an interface must be the same"; 236 sis = I1.class.getGenericInterfaces(); 237 assert 238 sis.length == 1 : 239 "I1 has one generic superinterface"; 240 assert 241 sis[0] == I3.class : 242 "Superinterface of I1 is I3"; 243 244 tvs = I2.class.getTypeParameters(); 245 assert 246 tvs.length == 3 : 247 "I3 has three formal type parameters"; 248 assert 249 tvs[0].getName().equals("E1") : 250 "Name of first formal type arg of I2 is E1"; 251 assert 252 tvs[1].getName().equals("E2") : 253 "Name of second formal type arg of I2 is E2"; 254 assert 255 tvs[2].getName().equals("E3") : 256 "Name of third formal type arg of I2 is E3"; 257 258 assert 259 I2.class.getGenericSuperclass() == I2.class.getSuperclass() : 260 "The generic and non-generic superclasses of an interface must be the same"; 261 262 tvs = I3.class.getTypeParameters(); 263 assert 264 tvs.length == 0 : 265 "I3 has no formal type parameters"; 266 267 assert 268 I3.class.getGenericSuperclass() == I3.class.getSuperclass() : 269 "The generic and non-generic superclasses of an interface must be the same"; 270 271 272 } 273 testTypeParameters()274 static void testTypeParameters() { 275 System.out.println("testing type parameters"); 276 TypeVariable[] tvs = cls.getTypeParameters(); 277 assert 278 tvs.length == 3 : 279 "C2 should have three type parameters"; 280 TypeVariable tv = tvs[0]; 281 Type[] bs = tv.getBounds(); 282 assert 283 bs.length == 1 : 284 "T1 should have one bound"; 285 assert 286 bs[0] instanceof ParameterizedType : 287 "The bound of T1 should be a parameterized type"; 288 289 tv = tvs[1]; 290 bs = tv.getBounds(); 291 assert 292 bs.length == 1 : 293 "T2 should have one bound"; 294 assert 295 bs[0] instanceof ParameterizedType : 296 "The bound of T2 should be a parameterized type"; 297 298 tv = tvs[2]; 299 bs = tv.getBounds(); 300 assert 301 bs.length == 1 : 302 "T3 should have one bound"; 303 assert 304 bs[0] == Throwable.class : 305 "The bound of T3 should be Throwable"; 306 } 307 testMethods()308 static void testMethods() throws NoSuchMethodException { 309 System.out.println("testing methods"); 310 311 312 313 Class[] params1 = new Class[3]; 314 params1[0] = Throwable.class; 315 params1[1] = C0.class; 316 params1[2] = C0.class; 317 318 Class[] params2 = new Class[1]; 319 params2[0] = Object.class; 320 321 Class[] params3 = new Class[1]; 322 params3[0] = C0.class; 323 324 Method mc1t = cls.getMethod("mc1t", params1); 325 Method mc1 = cls.getMethod("mc1", params2); 326 Method mt = cls.getMethod("mt", params3); 327 328 Type rt_mc1t = mc1t.getGenericReturnType(); 329 assert 330 rt_mc1t instanceof ParameterizedType : 331 "The return type of mc1t should be a parameterized type"; 332 ParameterizedType pt = (ParameterizedType) rt_mc1t; 333 334 assert 335 pt.getRawType() == C0.class : 336 "The raw return type of mc1t should be C0"; 337 338 Type[] tas = pt.getActualTypeArguments(); 339 assert 340 tas.length == 1 : 341 "Return type of mc1t should have one type argument"; 342 assert 343 tas[0] instanceof TypeVariable : 344 "Type argument of return type of mc1t is a type variable"; 345 346 Type rt_mc1 = mc1.getGenericReturnType(); 347 assert 348 rt_mc1 == C0.class : 349 "Return type of mc1 is C0"; 350 351 Type rt_mt = mt.getGenericReturnType(); 352 assert 353 rt_mt instanceof TypeVariable : 354 "Return type of mt is a type variable"; 355 356 Type[] pt_mc1t = mc1t.getGenericParameterTypes(); 357 358 assert 359 pt_mc1t.length == 3 : 360 "C0.mc1t has three parameters"; 361 Type p1_mc1t = pt_mc1t[0]; 362 assert p1_mc1t != null; 363 assert 364 p1_mc1t instanceof TypeVariable : 365 "Generic type of the 1st parameter of mc1t(T) is a type variable"; 366 TypeVariable tv = (TypeVariable) p1_mc1t; 367 368 assert 369 tv.getName().equals("T3") : 370 "Name of 1st type parameter of mc1t is T3, not " + tv.getName(); 371 Type[] bs = tv.getBounds(); 372 assert 373 bs.length == 1 : 374 "T3 should have one bound (mc1t)"; 375 assert 376 bs[0] == Throwable.class : 377 "The bound of T3 should be Throwable(mc1t)"; 378 379 Type p2_mc1t = pt_mc1t[1]; 380 assert 381 p2_mc1t instanceof ParameterizedType : 382 "The type of parameter 2 of mc1t is a parameterized type"; 383 pt = (ParameterizedType) p2_mc1t; 384 assert 385 pt.getRawType() == C0.class : 386 "Type of parameter 2 of mc1t is instantiation of C0"; 387 assert 388 pt.getOwnerType() == null : 389 "Type of parameter 2 of mc1t is has null owner"; 390 391 tas = pt.getActualTypeArguments(); 392 assert 393 tas.length == 1 : 394 "The type of parameter 2 of mc1t has one type argument"; 395 Type ta = tas[0]; 396 397 assert 398 ta instanceof TypeVariable : 399 "The actual type arg of C0<T> is a type variable (mc1t)"; 400 tv = (TypeVariable) ta; 401 assert 402 tv.getName().equals("T") : 403 "mc1t: Name of the type arg of C0<T> is T, not " + tv.getName(); 404 bs = tv.getBounds(); 405 assert 406 bs.length == 1 : 407 "mc1t: The type argument of C0<T> should have one bound"; 408 assert 409 bs[0] == Object.class : 410 "mc1t: The bound of the type arg of C0<T> should be Object"; 411 412 Type p3_mc1t = pt_mc1t[2]; 413 assert 414 p3_mc1t == C0.class : 415 "Type of parameter 3 of mc1t is C0"; 416 417 Type[] pt_mc1 = mc1.getGenericParameterTypes(); 418 assert 419 pt_mc1.length == 1 : 420 "C2.mc1 has one parameter"; 421 422 Type[] pt_mt = mt.getGenericParameterTypes(); 423 assert 424 pt_mt.length == 1 : 425 "C2.mt has one parameter"; 426 Type p_mt = pt_mt[0]; 427 assert 428 p_mt instanceof TypeVariable : 429 "The generic type of the parameter of mt(T) is a type variable"; 430 tv = (TypeVariable) p_mt; 431 assert 432 tv.getName().equals("T2") : 433 "The name of the type parameter of mt is T2, not " + tv.getName(); 434 bs = tv.getBounds(); 435 assert 436 bs.length == 1 : 437 "T2 should have one bound"; 438 assert 439 bs[0] instanceof ParameterizedType: 440 "The bound of T2 should be parameterized type"; 441 442 Type[] et_mc1t = mc1t.getGenericExceptionTypes(); 443 assert 444 et_mc1t.length == 0 : 445 "Method C0.mc1t should have no generic exception types"; 446 447 Type[] et_mc1 = mc1.getGenericExceptionTypes(); 448 assert 449 et_mc1.length == 0 : 450 "Method C0.mc1 should have no generic exception types"; 451 452 Type[] et_mt = mt.getGenericExceptionTypes(); 453 assert 454 et_mt.length == 0 : 455 "Method C0.mt should have no generic exception types"; 456 457 458 TypeVariable[] tv_mc1t = mc1t.getTypeParameters(); 459 assert 460 tv_mc1t.length == 1 : 461 "Method C2.mc1t should have one type parameter"; 462 463 TypeVariable[] tv_mc1 = mc1.getTypeParameters(); 464 assert 465 tv_mc1.length == 2 : 466 "Method C2.mc1 should have two type parameters"; 467 468 TypeVariable[] tv_mt = mt.getTypeParameters(); 469 assert 470 tv_mt.length == 0 : 471 "Method C2.mt should have no type parameters"; 472 } 473 474 testFields()475 static void testFields() throws NoSuchFieldException{ 476 System.out.println("testing fields"); 477 Field ft = cls. getField("ft"); 478 Field fc1t = cls. getField("fc1t"); 479 Field fc1 = cls. getField("fc1"); 480 Field fi = cls. getField("fi"); 481 482 Type gt_ft = ft.getGenericType(); 483 assert 484 gt_ft instanceof TypeVariable : 485 "The generic type of C0.ft is a type variable"; 486 TypeVariable tv = (TypeVariable) gt_ft; 487 assert 488 tv.getName().equals("T1") : 489 "The name of the type of ft is T1, not " + tv.getName(); 490 Type[] bs = tv.getBounds(); 491 assert 492 bs.length == 1 : 493 "The type of ft should have one bound"; 494 495 496 Type gt_fc1t = fc1t.getGenericType(); 497 assert 498 gt_fc1t instanceof ParameterizedType : 499 "The generic type of C0.fc1t is a parameterized type"; 500 ParameterizedType pt = (ParameterizedType) gt_fc1t; 501 assert 502 pt.getRawType() == C0.class : 503 "Type of C2.fc1t is an instantiation of C0"; 504 assert 505 pt.getOwnerType() == null : 506 "Type of C2.fc1t is has null owner"; 507 Type[] tas = pt.getActualTypeArguments(); 508 assert 509 tas.length == 1 : 510 "The type of fc1t has one type argument"; 511 Type ta = tas[0]; 512 513 assert 514 ta == String.class : 515 "The actual type arg of C0<String> is String"; 516 517 518 Type gt_fc1 = fc1.getGenericType(); 519 assert 520 gt_fc1 == C0.class : 521 " Type of C2.fc1 should be C0"; 522 523 Type gt_fi = fi.getGenericType(); 524 assert 525 gt_fi == int.class: 526 " Type of C2.fi should be int"; 527 528 } 529 testConstructors()530 static void testConstructors() throws NoSuchMethodException { 531 System.out.println("testing constructors"); 532 Class[] params1 = new Class[1]; 533 params1[0] = C0.class; 534 Constructor<C2> con = cls.getDeclaredConstructor(params1); 535 536 Type[] pt_con = con.getGenericParameterTypes(); 537 assert 538 pt_con.length == 1 : 539 "Constructor C0(T) should have one generic parameter type"; 540 Type pt = pt_con[0]; 541 assert 542 pt instanceof TypeVariable : 543 "The generic type of the parameter of C0(T2) is a type variable"; 544 TypeVariable tv = (TypeVariable) pt; 545 assert 546 tv.getName().equals("T2") : 547 "The name of the type parameter of C2 is T2, not " + tv.getName(); 548 Type[] bs = tv.getBounds(); 549 assert 550 bs.length == 1 : 551 "T should have one bound"; 552 553 554 Type[] et_con = con.getGenericExceptionTypes(); 555 assert 556 et_con.length == 0 : 557 "Constructor C2(T2) should have no generic exception types"; 558 559 TypeVariable[] tv_con = con.getTypeParameters(); 560 assert 561 tv_con.length == 0 : 562 "Constructor C2(T2) should have no type parameters"; 563 564 565 Class[] params2 = new Class[1]; 566 params2[0] = Object.class; 567 con = cls.getDeclaredConstructor(params2); 568 569 pt_con = con.getGenericParameterTypes(); 570 assert 571 pt_con.length == 1 : 572 "Constructor C0(T) should have one generic parameter type"; 573 pt = pt_con[0]; 574 assert 575 pt instanceof TypeVariable : 576 "The generic type of the parameter of C2(T) is a type variable"; 577 tv = (TypeVariable) pt; 578 assert 579 tv.getName().equals("T") : 580 "The name of the type parameter of C2 is T, not " + tv.getName(); 581 bs = tv.getBounds(); 582 assert 583 bs.length == 1 : 584 "T should have one bound"; 585 586 587 et_con = con.getGenericExceptionTypes(); 588 assert 589 et_con.length == 0 : 590 "Constructor C2(T) should have no generic exception types"; 591 592 tv_con = con.getTypeParameters(); 593 assert 594 tv_con.length == 1 : 595 "Constructor C2(T) should have one type parameter"; 596 597 Class[] params3 = new Class[3]; 598 params3[0] = Object.class; 599 params3[1] = Object.class; 600 params3[2] = Object.class; 601 602 con = cls.getDeclaredConstructor(params3); 603 604 pt_con = con.getGenericParameterTypes(); 605 assert 606 pt_con.length == 3 : 607 "Constructor C2(T1,T2,T4) should have three generic parameter types"; 608 pt = pt_con[0]; 609 assert 610 pt instanceof TypeVariable : 611 "The generic type of the first parameter of C2(T1,T2,T4) is a type variable"; 612 tv = (TypeVariable) pt; 613 assert 614 tv.getName().equals("T1") : 615 "The name of the type parameter of C2(T1,T2,T4) is T1, not " + tv.getName(); 616 bs = tv.getBounds(); 617 assert 618 bs.length == 1 : 619 "T should have one bound"; 620 621 622 et_con = con.getGenericExceptionTypes(); 623 assert 624 et_con.length == 0 : 625 "Constructor C2(T1,T2,T4) should have no generic exception types"; 626 627 tv_con = con.getTypeParameters(); 628 assert 629 tv_con.length == 4 : 630 "Constructor C2(T1,T2,T4) should have four type parameters"; 631 632 Class[] params4 = new Class[0]; 633 con = cls.getDeclaredConstructor(params4); 634 635 pt_con = con.getGenericParameterTypes(); 636 assert 637 pt_con.length == 0 : 638 "Constructor C2() should have no generic parameter types"; 639 640 641 et_con = con.getGenericExceptionTypes(); 642 assert 643 et_con.length == 1 : 644 "Constructor C2() should have one generic exception type"; 645 646 tv_con = con.getTypeParameters(); 647 assert 648 tv_con.length == 0 : 649 "Constructor C2() should have no type parameters"; 650 651 652 } 653 } 654