JDK-6209029 : The type of a class literal shouldn't be erased
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Rejected
  • OS: generic
  • CPU: generic
  • Submitted: 2004-12-15
  • Updated: 2025-05-05
  • Resolved: 2025-05-05
Related Reports
Relates :  
Relates :  
Relates :  
Description
This program doesn't compile:

class Test {
    void test(String name) {
	Class<? extends Enum<?>> enumClass
	    = Class.forName(name).asSubclass(Enum.class);
    }
}


###@###.### 2004-12-15 17:02:48 GMT

Comments
SUGGESTED FIX Index: src/share/classes/com/sun/tools/javac/comp/Attr.java =========================================================== @@ -1140,7 +1133,7 @@ restype = new ClassType(restype.outer(), Type.emptyList.prepend - (new ArgumentType(types.erasure(qualifier), + (new ArgumentType(types.glob(qualifier), BoundKind.EXTENDS, syms.boundClass)), restype.tsym); @@ -1788,7 +1781,7 @@ // visitSelect that qualifier expression is a type. Type t = syms.classType; List<Type> typeargs = allowGenerics - ? Type.emptyList.prepend(types.erasure(site)) + ? Type.emptyList.prepend(types.glob(site)) : Type.emptyList; t = new ClassType(t.outer(), typeargs, t.tsym); return new VarSymbol( Index: src/share/classes/com/sun/tools/javac/code/Types.java ============================================================ @@ -1654,6 +1654,23 @@ return Type.map(these, erasureFun); } + public Type glob(Type t) { + t = erasure(t); + if (t.tag == CLASS) { + while (t != t.tsym.type) + t = t.tsym.type; + List<Type> formals = t.allparams(); + ListBuffer<Type> wildcards = new ListBuffer<Type>(); + for (Type formal : formals) + wildcards = wildcards.append(new ArgumentType(syms.objectType, + BoundKind.UNBOUND, + syms.boundClass).withTypeVar(formal)); + return subst(t, formals, wildcards.toList()); + } else { + return t; + } + } + /************************************************************ * Type makeCompoundType(List<Type> bounds, Type supertype) * Type makeCompoundType(List<Type> bounds) ###@###.### 2004-12-17 09:46:50 GMT
17-12-2004

EVALUATION It is unlikely that we will change the type rules to allow the following: Class<? extends Enum<?>> cooked = null; Class<? extends Enum> rare = null; cooked = rare; The reason is that we don't want to support "rare" types, that is mixing raw and cooked types. The rationale is that raw types are provided for compatibility reasons only. If you find you need to mix raw and cooked types, then something is wrong. In this case, what is likely wrong is the static type of java.lang.Object.getClass and the static type of type tokens (aka class literals). See 6184881. So we are likely to fix the problem reported, but not the above "cooked = raw" assignment. ###@###.### 2004-12-16 20:13:09 GMT
16-12-2004