From a9f457a94ebcc8f1e24e169b4b49d0f69ba83cf0 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 18 Jul 2016 10:27:58 -0700 Subject: [PATCH] 8161500: Use getTypeName and StringJoiner in core reflection toString methods Reviewed-by: redestad --- .../share/classes/java/lang/Class.java | 10 +-- .../classes/java/lang/reflect/Executable.java | 61 ++++++++----------- .../GenericArrayTypeImpl.java | 12 +--- .../ParameterizedTypeImpl.java | 22 +++---- .../reflectiveObjects/WildcardTypeImpl.java | 13 ++-- .../java/lang/Class/GenericStringTest.java | 18 +++--- .../Constructor/GenericStringTest.java | 10 +-- .../lang/reflect/Field/GenericStringTest.java | 16 ++--- .../reflect/Method/GenericStringTest.java | 38 +++++++++--- 9 files changed, 89 insertions(+), 111 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 4649b04b135..7ac3d50202c 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -238,15 +238,11 @@ public final class Class implements java.io.Serializable, TypeVariable[] typeparms = component.getTypeParameters(); if (typeparms.length > 0) { - boolean first = true; - sb.append('<'); + StringJoiner sj = new StringJoiner(",", "<", ">"); for(TypeVariable typeparm: typeparms) { - if (!first) - sb.append(','); - sb.append(typeparm.getTypeName()); - first = false; + sj.add(typeparm.getTypeName()); } - sb.append('>'); + sb.append(sj.toString()); } for (int i = 0; i < arrayDepth; i++) diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java index 88a9f5de9ac..812e22816f1 100644 --- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -28,6 +28,7 @@ package java.lang.reflect; import java.lang.annotation.*; import java.util.Map; import java.util.Objects; +import java.util.StringJoiner; import jdk.internal.misc.SharedSecrets; import sun.reflect.annotation.AnnotationParser; @@ -86,15 +87,6 @@ public abstract class Executable extends AccessibleObject getDeclaringClass()); } - void separateWithCommas(Class[] types, StringBuilder sb) { - for (int j = 0; j < types.length; j++) { - sb.append(types[j].getTypeName()); - if (j < (types.length - 1)) - sb.append(","); - } - - } - void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) { int mod = getModifiers() & mask; @@ -121,13 +113,20 @@ public abstract class Executable extends AccessibleObject printModifiersIfNonzero(sb, modifierMask, isDefault); specificToStringHeader(sb); - sb.append('('); - separateWithCommas(parameterTypes, sb); + StringJoiner sj = new StringJoiner(","); + for (Class parameterType : parameterTypes) { + sj.add(parameterType.getTypeName()); + } + sb.append(sj.toString()); sb.append(')'); + if (exceptionTypes.length > 0) { - sb.append(" throws "); - separateWithCommas(exceptionTypes, sb); + StringJoiner joiner = new StringJoiner(",", "throws ", ""); + for (Class exceptionType : exceptionTypes) { + joiner.add(exceptionType.getTypeName()); + } + sb.append(joiner.toString()); } return sb.toString(); } catch (Exception e) { @@ -149,42 +148,34 @@ public abstract class Executable extends AccessibleObject TypeVariable[] typeparms = getTypeParameters(); if (typeparms.length > 0) { - boolean first = true; - sb.append('<'); + StringJoiner sj = new StringJoiner(",", "<", "> "); for(TypeVariable typeparm: typeparms) { - if (!first) - sb.append(','); - // Class objects can't occur here; no need to test - // and call Class.getName(). - sb.append(typeparm.toString()); - first = false; + sj.add(typeparm.getTypeName()); } - sb.append("> "); + sb.append(sj.toString()); } specificToGenericStringHeader(sb); sb.append('('); + StringJoiner sj = new StringJoiner(","); Type[] params = getGenericParameterTypes(); for (int j = 0; j < params.length; j++) { String param = params[j].getTypeName(); if (isVarArgs() && (j == params.length - 1)) // replace T[] with T... param = param.replaceFirst("\\[\\]$", "..."); - sb.append(param); - if (j < (params.length - 1)) - sb.append(','); + sj.add(param); } + sb.append(sj.toString()); sb.append(')'); - Type[] exceptions = getGenericExceptionTypes(); - if (exceptions.length > 0) { - sb.append(" throws "); - for (int k = 0; k < exceptions.length; k++) { - sb.append((exceptions[k] instanceof Class)? - ((Class)exceptions[k]).getName(): - exceptions[k].toString()); - if (k < (exceptions.length - 1)) - sb.append(','); + + Type[] exceptionTypes = getGenericExceptionTypes(); + if (exceptionTypes.length > 0) { + StringJoiner joiner = new StringJoiner(",", " throws ", ""); + for (Type exceptionType : exceptionTypes) { + joiner.add(exceptionType.getTypeName()); } + sb.append(joiner.toString()); } return sb.toString(); } catch (Exception e) { diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java index fb0718e920a..941c96625cf 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -65,15 +65,7 @@ public class GenericArrayTypeImpl } 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(); + return getGenericComponentType().getTypeName() + "[]"; } @Override diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java index aca919f46ed..0f0701023dc 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -33,6 +33,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Arrays; +import java.util.StringJoiner; import java.util.Objects; /** Implementing class for ParameterizedType interface. */ @@ -207,10 +208,7 @@ public class ParameterizedTypeImpl implements ParameterizedType { StringBuilder sb = new StringBuilder(); if (ownerType != null) { - if (ownerType instanceof Class) - sb.append(((Class)ownerType).getName()); - else - sb.append(ownerType.toString()); + sb.append(ownerType.getTypeName()); sb.append("."); @@ -224,17 +222,13 @@ public class ParameterizedTypeImpl implements ParameterizedType { } else sb.append(rawType.getName()); - if (actualTypeArguments != null && - actualTypeArguments.length > 0) { - sb.append("<"); - boolean first = true; + if (actualTypeArguments != null) { + StringJoiner sj = new StringJoiner(", ", "<", ">"); + sj.setEmptyValue(""); for(Type t: actualTypeArguments) { - if (!first) - sb.append(", "); - sb.append(t.getTypeName()); - first = false; + sj.add(t.getTypeName()); } - sb.append(">"); + sb.append(sj.toString()); } return sb.toString(); diff --git a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java index 0208a296f6e..71887bd642e 100644 --- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java +++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -32,6 +32,7 @@ import sun.reflect.generics.factory.GenericsFactory; import sun.reflect.generics.tree.FieldTypeSignature; import sun.reflect.generics.visitor.Reifier; import java.util.Arrays; +import java.util.StringJoiner; /** @@ -156,14 +157,12 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator assert bounds.length > 0; - boolean first = true; + StringJoiner sj = new StringJoiner(" & "); for(Type bound: bounds) { - if (!first) - sb.append(" & "); - - first = false; - sb.append(bound.getTypeName()); + sj.add(bound.getTypeName()); } + sb.append(sj.toString()); + return sb.toString(); } diff --git a/jdk/test/java/lang/Class/GenericStringTest.java b/jdk/test/java/lang/Class/GenericStringTest.java index 176fcab043a..bb002591c32 100644 --- a/jdk/test/java/lang/Class/GenericStringTest.java +++ b/jdk/test/java/lang/Class/GenericStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6298888 6992705 + * @bug 6298888 6992705 8161500 * @summary Check Class.toGenericString() * @author Joseph D. Darcy */ @@ -58,15 +58,11 @@ public class GenericStringTest { f = GenericStringTest.class.getDeclaredField("mixed2"); failures += checkToGenericString(f.getType(), "java.util.Map[][]"); - Class[] types = { - GenericStringTest.class, - AnInterface.class, - LocalMap.class, - AnEnum.class, - AnotherEnum.class, - }; - - for(Class clazz : types) { + for(Class clazz : List.of(GenericStringTest.class, + AnInterface.class, + LocalMap.class, + AnEnum.class, + AnotherEnum.class)) { failures += checkToGenericString(clazz, clazz.getAnnotation(ExpectedGenericString.class).value()); } diff --git a/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java b/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java index bc049fc3f0c..68e192bbffe 100644 --- a/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java +++ b/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 5033583 6316717 6470106 + * @bug 5033583 6316717 6470106 8161500 * @summary Check toGenericString() and toString() methods * @author Joseph D. Darcy */ @@ -35,12 +35,8 @@ import java.util.*; public class GenericStringTest { public static void main(String argv[]) throws Exception{ int failures = 0; - List> classList = new LinkedList>(); - classList.add(TestClass1.class); - classList.add(TestClass2.class); - - for(Class clazz: classList) + for(Class clazz: List.of(TestClass1.class, TestClass2.class)) for(Constructor ctor: clazz.getDeclaredConstructors()) { ExpectedGenericString egs = ctor.getAnnotation(ExpectedGenericString.class); String actual = ctor.toGenericString(); diff --git a/jdk/test/java/lang/reflect/Field/GenericStringTest.java b/jdk/test/java/lang/reflect/Field/GenericStringTest.java index 3c93472e1d4..65fbbc43381 100644 --- a/jdk/test/java/lang/reflect/Field/GenericStringTest.java +++ b/jdk/test/java/lang/reflect/Field/GenericStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 5033583 + * @bug 5033583 8161500 * @summary Check toGenericString() method * @author Joseph D. Darcy */ @@ -35,12 +35,8 @@ import java.util.*; public class GenericStringTest { public static void main(String argv[]) throws Exception { int failures = 0; - List classList = new LinkedList(); - classList.add(TestClass1.class); - classList.add(TestClass2.class); - - for(Class clazz: classList) + for(Class clazz: List.of(TestClass1.class, TestClass2.class)) for(Field field: clazz.getDeclaredFields()) { ExpectedString es = field.getAnnotation(ExpectedString.class); String genericString = field.toGenericString(); @@ -61,15 +57,15 @@ public class GenericStringTest { class TestClass1 { @ExpectedString("int TestClass1.field1") - int field1; + int field1; @ExpectedString("private static java.lang.String TestClass1.field2") - private static String field2; + private static String field2; } class TestClass2 { @ExpectedString("public E TestClass2.field1") - public E field1; + public E field1; } @Retention(RetentionPolicy.RUNTIME) diff --git a/jdk/test/java/lang/reflect/Method/GenericStringTest.java b/jdk/test/java/lang/reflect/Method/GenericStringTest.java index b169c216be6..43fa70675d6 100644 --- a/jdk/test/java/lang/reflect/Method/GenericStringTest.java +++ b/jdk/test/java/lang/reflect/Method/GenericStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 5033583 6316717 6470106 8004979 + * @bug 5033583 6316717 6470106 8004979 8161500 * @summary Check toGenericString() and toString() methods * @author Joseph D. Darcy */ @@ -35,14 +35,9 @@ import java.util.*; public class GenericStringTest { public static void main(String argv[]) throws Exception { int failures = 0; - List> classList = new LinkedList>(); - classList.add(TestClass1.class); - classList.add(TestClass2.class); - classList.add(Roebling.class); - classList.add(TestInterface1.class); - - for(Class clazz: classList) + for(Class clazz: List.of(TestClass1.class, TestClass2.class, + Roebling.class, TestInterface1.class)) for(Method method: clazz.getDeclaredMethods()) { ExpectedGenericString egs = method.getAnnotation(ExpectedGenericString.class); if (egs != null) { @@ -121,6 +116,30 @@ class TestClass2 { @ExpectedGenericString( "public void TestClass2.method2() throws F") public void method2() throws F {return;} + + @ExpectedGenericString( + "public E[] TestClass2.method3()") + public E[] method3() {return null;} + + @ExpectedGenericString( + "public E[][] TestClass2.method4()") + public E[][] method4() {return null;} + + @ExpectedGenericString( + "public java.util.List TestClass2.method5()") + public List method5() {return null;} + + @ExpectedGenericString( + "public java.util.List TestClass2.method6()") + public List method6() {return null;} + + @ExpectedGenericString( + "public java.util.List[] TestClass2.method7()") + public List[] method7() {return null;} + + @ExpectedGenericString( + "public java.util.Map TestClass2.method8()") + public Map method8() {return null;} } class Roebling implements Comparable { @@ -157,7 +176,6 @@ interface TestInterface1 { @ExpectedGenericString( "public default strictfp double TestInterface1.quux()") strictfp default double quux(){return 1.0;} - } @Retention(RetentionPolicy.RUNTIME)