JDK-5015676 : (reflect) Concrete Type classes could define toString()
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 5.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2004-03-18
  • Updated: 2012-09-28
  • Resolved: 2004-04-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b48Fixed
Related Reports
Duplicate :  
Relates :  
Description
The Type instances that you get back from e.g. Method.getGenericReturnType() could define useful toString() methods.  At the moment you get the default string, such as "sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl@1e0be38".  Existing reflection classes do define useful toString() methods, e.g. Method.toString() which may return "public abstract java.util.Set T.stringSet()".  Having a useful toString() makes it much easier to produce meaningful exception messages in code that uses reflection ("Could not map " + parameterizedType + " to a factory").

Incidentally Method.toString() could then use getGenericReturnType() and getGenericParameterTypes() instead of getReturnType() and getParameterTypes().

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b48 tiger-beta2
14-06-2004

WORK AROUND Roll your own, e.g. (incomplete): private static String toString(Type t) { if (t instanceof Class) return ((Class) t).getName(); else if (t instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) t; StringBuilder b = new StringBuilder(); b.append(toString(pt.getRaw())).append("<"); Type[] actuals = pt.getActualTypes(); for (int i = 0; i < actuals.length; i++) { if (i > 0) b.append(", "); b.append(toString(actuals[i])); } return b.append(">").toString(); } else return t.toString(); } (The initial version of this workaround contained bugs.)
11-06-2004

PUBLIC COMMENTS The Type instances that you get back from e.g. Method.getGenericReturnType() could define useful toString() methods. At the moment you get the default string, such as "sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl@1e0be38". Existing reflection classes do define useful toString() methods, e.g. Method.toString() which may return "public abstract java.util.Set T.stringSet()". Having a useful toString() makes it much easier to produce meaningful exception messages in code that uses reflection ("Could not map " + parameterizedType + " to a factory").
10-06-2004

SUGGESTED FIX src/share/classes/sun/reflect/generics/reflectiveObjects>sccs sccsdiff -r1.2 -r1.3 ParameterizedTypeImpl.java ------- ParameterizedTypeImpl.java ------- 134a135,174 > > public String toString() { > StringBuilder sb = new StringBuilder(); > > if (ownerType != null) { > if (ownerType instanceof Class) > sb.append(((Class)ownerType).getName()); > else > sb.append(ownerType.toString()); > > sb.append("."); > > if (ownerType instanceof ParameterizedTypeImpl) { > // Find simple name of nested type by removing the > // shared prefix with owner. > sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$", > "")); > } else > sb.append(rawType.getName()); > } else > sb.append(rawType.getName()); > > if (actualTypeArguments != null && > actualTypeArguments.length > 0) { > sb.append("<"); > boolean first = true; > for(Type t: actualTypeArguments) { > if (!first) > sb.append(", "); > if (t instanceof Class) > sb.append(((Class)t).getName()); > else > sb.append(t.toString()); > first = false; > } > sb.append(">"); > } > > return sb.toString(); > } src/share/classes/sun/reflect/generics/reflectiveObjects>sccs sccsdiff -r1.3 -r1.4 TypeVariableImpl.java ------- TypeVariableImpl.java ------- 136a137 > public String toString() {return getName();} src/share/classes/sun/reflect/generics/reflectiveObjects>sccs sccsdiff -r1.3 -r1.4 WildcardTypeImpl.java ------- WildcardTypeImpl.java ------- 104a105 > 161a163,194 > > public String toString() { > Type[] lowerBounds = getLowerBounds(); > Type[] bounds = lowerBounds; > StringBuilder sb = new StringBuilder(); > > if (lowerBounds.length > 0) > sb.append("? super "); > else { > Type[] upperBounds = getUpperBounds(); > if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) { > bounds = upperBounds; > sb.append("? extends "); > } else > return "?"; > } > > assert bounds.length > 0; > > boolean first = true; > for(Type bound: bounds) { > if (!first) > sb.append(" & "); > > first = false; > if (bound instanceof Class) > sb.append(((Class)bound).getName() ); > else > sb.append(bound.toString()); > } > return sb.toString(); > } src/share/classes/sun/reflect/generics/reflectiveObjects>sccs sccsdiff -r1.2 -r1.3 GenericArrayTypeImpl.java ------- GenericArrayTypeImpl.java ------- 47a48,59 > > public String toString() { > Type componentType = getGenericComponentType(); > StringBuilder sb = new StringBuilder(); > > if (componentType instanceof Class) > sb.append(((Class)componentType).getName() ); > else > sb.append(componentType.toString()); > sb.append("[]"); > return sb.toString(); > } ###@###.### 2004-04-12
12-04-2004

EVALUATION A reasonable request; will try to address this for Tiger. ###@###.### 2004-03-18
18-03-2004