8060077: Class.toGenericString specification doesn't mention array types

Reviewed-by: psandoz, jfranck
This commit is contained in:
Joe Darcy 2015-01-16 14:04:27 -08:00
parent f97da65885
commit 9800aaa84a
2 changed files with 62 additions and 23 deletions

View File

@ -149,7 +149,8 @@ public final class Class<T> implements java.io.Serializable,
* {@code getName}. If this {@code Class} object represents a
* primitive type, this method returns the name of the primitive type. If
* this {@code Class} object represents void this method returns
* "void".
* "void". If this {@code Class} object represents an array type,
* this method returns "class " followed by {@code getName}.
*
* @return a string representation of this class object.
*/
@ -174,6 +175,12 @@ public final class Class<T> implements java.io.Serializable,
* occur in canonical order. If there are no type parameters, the
* type parameter list is elided.
*
* For an array type, the string starts with the type name,
* followed by an angle-bracketed comma-separated list of the
* type's type parameters, if any, followed by a sequence of
* {@code []} characters, one set of brackets per dimension of
* the array.
*
* <p>Note that since information about the runtime representation
* of a type is being generated, modifiers not present on the
* originating source code or illegal on the originating source
@ -189,29 +196,39 @@ public final class Class<T> implements java.io.Serializable,
return toString();
} else {
StringBuilder sb = new StringBuilder();
Class<?> component = this;
int arrayDepth = 0;
// Class modifiers are a superset of interface modifiers
int modifiers = getModifiers() & Modifier.classModifiers();
if (modifiers != 0) {
sb.append(Modifier.toString(modifiers));
sb.append(' ');
}
if (isAnnotation()) {
sb.append('@');
}
if (isInterface()) { // Note: all annotation types are interfaces
sb.append("interface");
if (isArray()) {
do {
arrayDepth++;
component = component.getComponentType();
} while (component.isArray());
sb.append(component.getName());
} else {
if (isEnum())
sb.append("enum");
else
sb.append("class");
}
sb.append(' ');
sb.append(getName());
// Class modifiers are a superset of interface modifiers
int modifiers = getModifiers() & Modifier.classModifiers();
if (modifiers != 0) {
sb.append(Modifier.toString(modifiers));
sb.append(' ');
}
TypeVariable<?>[] typeparms = getTypeParameters();
if (isAnnotation()) {
sb.append('@');
}
if (isInterface()) { // Note: all annotation types are interfaces
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
else
sb.append("class");
}
sb.append(' ');
sb.append(getName());
}
TypeVariable<?>[] typeparms = component.getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
@ -224,6 +241,9 @@ public final class Class<T> implements java.io.Serializable,
sb.append('>');
}
for (int i = 0; i < arrayDepth; i++)
sb.append("[]");
return sb.toString();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, 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
@ -34,10 +34,29 @@ import java.util.*;
@ExpectedGenericString("public class GenericStringTest")
public class GenericStringTest {
public static void main(String... args){
public Map<String, Integer>[] mixed = null;
public Map<String, Integer>[][] mixed2 = null;
public static void main(String... args) throws ReflectiveOperationException {
int failures = 0;
String[][] nested = {{""}};
int[][] intArray = {{1}};
failures += checkToGenericString(int.class, "int");
failures += checkToGenericString(void.class, "void");
failures += checkToGenericString(args.getClass(), "java.lang.String[]");
failures += checkToGenericString(nested.getClass(), "java.lang.String[][]");
failures += checkToGenericString(intArray.getClass(), "int[][]");
failures += checkToGenericString(java.util.Map.class, "public abstract interface java.util.Map<K,V>");
Field f = GenericStringTest.class.getDeclaredField("mixed");
// The expected value includes "<K,V>" rather than
// "<...String,...Integer>" since the Class object rather than
// Type objects is being queried.
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[]");
f = GenericStringTest.class.getDeclaredField("mixed2");
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[][]");
Class<?>[] types = {
GenericStringTest.class,