/* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 5041784 * @summary Check that plain arrays like String[] are never represented as * GenericArrayType. * @author Eamonn McManus */ import java.lang.reflect.Constructor; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; public class TestPlainArrayNotGeneric { public String[] m1(List p1) {return null;} public List m2(String[] p1) {return null;} public void m3(List p1, String[] p2) {} public void m4(List p1) {} public TestPlainArrayNotGeneric(List p1) {} public TestPlainArrayNotGeneric(List p1, String[] p2) {} public > T m5(T p1) {return null;} public T[] m6(T[] p1, List p2) {return null;} public List m6(List p1) {return null;} public > T m7(T[] p1) {return null;} public List m8(List p1) {return null;} public > T[] m9(T[] p1) {return null;} public static interface XMap extends Map, String[]> {} public static interface YMap, V> extends Map {} private static String lastFailure; private static int failureCount; public static void main(String[] args) throws Exception { checkClass(TestPlainArrayNotGeneric.class); if (failureCount == 0) System.out.println("TEST PASSED"); else throw new Exception("TEST FAILED: Last failure: " + lastFailure); } private static void checkClass(Class c) throws Exception { Method[] methods = c.getMethods(); for (Method m : methods) { check(m.getGenericReturnType(), "return type of method " + m); check(m.getGenericParameterTypes(), "parameter", "method " + m); check(m.getTypeParameters(), "type parameter", "method " + m); } Constructor[] constructors = c.getConstructors(); for (Constructor constr : constructors) { check(constr.getGenericParameterTypes(), "parameter", "constructor " + constr); check(constr.getTypeParameters(), "type parameter", "constructor " + constr); } Class[] inners = c.getDeclaredClasses(); for (Class inner : inners) checkClass(inner); } private static void check(Type[] types, String elementKind, String what) { for (int i = 0; i < types.length; i++) { Type t = types[i]; check(t, elementKind + " " + (i+1) + " of " + what); } } private static final Set checking = new HashSet<>(); private static void check(Type t, String what) { if (t == null || !checking.add(t)) return; // Avoid infinite recursion. t can be null e.g. for superclass of Object. try { check2(t, what); } finally { checking.remove(t); } } private static void check2(Type t, String what) { if (t instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) t; check(pt.getActualTypeArguments(), "type argument", what); } else if (t instanceof TypeVariable) { TypeVariable tv = (TypeVariable) t; check(tv.getBounds(), "bound", what); GenericDeclaration gd = tv.getGenericDeclaration(); if (gd instanceof Type) check((Type) gd, "declaration containing " + what); } else if (t instanceof WildcardType) { WildcardType wt = (WildcardType) t; check(wt.getLowerBounds(), "lower bound", "wildcard type in " + what); check(wt.getUpperBounds(), "upper bound", "wildcard type in " + what); } else if (t instanceof Class) { Class c = (Class) t; check(c.getGenericInterfaces(), "superinterface", c.toString()); check(c.getGenericSuperclass(), "superclass of " + c); check(c.getTypeParameters(), "type parameter", c.toString()); } else if (t instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) t; Type comp = gat.getGenericComponentType(); if (comp instanceof Class) { fail("Type " + t + " uses GenericArrayType when plain " + "array would do, in " + what); } else check(comp, "component type of " + what); } else { fail("TEST BUG: mutant Type " + t + " (a " + t.getClass().getName() + ")"); } } private static void fail(String why) { System.out.println("FAIL: " + why); lastFailure = why; failureCount++; } }