--- a/src/java.base/share/classes/java/lang/Class.java Thu Nov 01 15:11:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java Thu Nov 01 20:37:45 2018 -0700
@@ -59,6 +59,8 @@
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
+import java.util.stream.Stream;
+import java.util.stream.Collectors;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.loader.BootLoader;
@@ -200,7 +202,8 @@
* and {@code class}, {@code enum}, {@code interface}, or
* <code>@</code>{@code interface}, as appropriate), followed
* by the type's name, followed by an angle-bracketed
- * comma-separated list of the type's type parameters, if any.
+ * comma-separated list of the type's type parameters, if any,
+ * including informative bounds on the type parameters, if any.
*
* A space is used to separate modifiers from one another and to
* separate any modifiers from the kind of type. The modifiers
@@ -262,11 +265,8 @@
TypeVariable<?>[] typeparms = component.getTypeParameters();
if (typeparms.length > 0) {
- StringJoiner sj = new StringJoiner(",", "<", ">");
- for(TypeVariable<?> typeparm: typeparms) {
- sj.add(typeparm.getTypeName());
- }
- sb.append(sj.toString());
+ sb.append(Stream.of(typeparms).map(Class::typeVarBounds).
+ collect(Collectors.joining(",", "<", ">")));
}
for (int i = 0; i < arrayDepth; i++)
@@ -276,6 +276,17 @@
}
}
+ static String typeVarBounds(TypeVariable<?> typeVar) {
+ Type[] bounds = typeVar.getBounds();
+ if (bounds.length == 1 && bounds[0].equals(Object.class)) {
+ return typeVar.getName();
+ } else {
+ return typeVar.getName() + " extends " +
+ Stream.of(bounds).map(Type::getTypeName).
+ collect(Collectors.joining(" & "));
+ }
+ }
+
/**
* Returns the {@code Class} object associated with the class or
* interface with the given string name. Invoking this method is
@@ -3399,14 +3410,14 @@
* Helper method to get the method name from arguments.
*/
private String methodToString(String name, Class<?>[] argTypes) {
- StringJoiner sj = new StringJoiner(", ", getName() + "." + name + "(", ")");
+ StringBuilder sb = new StringBuilder();
+ sb.append(getName() + "." + name + "(");
if (argTypes != null) {
- for (int i = 0; i < argTypes.length; i++) {
- Class<?> c = argTypes[i];
- sj.add((c == null) ? "null" : c.getName());
- }
+ Stream.of(argTypes).map(c -> {return (c == null) ? "null" : c.getName();}).
+ collect(Collectors.joining(","));
}
- return sj.toString();
+ sb.append(")");
+ return sb.toString();
}
/** use serialVersionUID from JDK 1.1 for interoperability */