51 import java.security.PrivilegedAction; |
51 import java.security.PrivilegedAction; |
52 import java.util.ArrayList; |
52 import java.util.ArrayList; |
53 import java.util.Arrays; |
53 import java.util.Arrays; |
54 import java.util.Collection; |
54 import java.util.Collection; |
55 import java.util.HashMap; |
55 import java.util.HashMap; |
56 import java.util.HashSet; |
|
57 import java.util.LinkedHashMap; |
56 import java.util.LinkedHashMap; |
|
57 import java.util.LinkedHashSet; |
58 import java.util.List; |
58 import java.util.List; |
59 import java.util.Map; |
59 import java.util.Map; |
60 import java.util.Objects; |
60 import java.util.Objects; |
61 import java.util.Set; |
|
62 import java.util.StringJoiner; |
61 import java.util.StringJoiner; |
63 |
62 |
64 import jdk.internal.HotSpotIntrinsicCandidate; |
63 import jdk.internal.HotSpotIntrinsicCandidate; |
65 import jdk.internal.loader.BootLoader; |
64 import jdk.internal.loader.BootLoader; |
66 import jdk.internal.loader.BuiltinClassLoader; |
65 import jdk.internal.loader.BuiltinClassLoader; |
1769 public Field[] getFields() throws SecurityException { |
1768 public Field[] getFields() throws SecurityException { |
1770 SecurityManager sm = System.getSecurityManager(); |
1769 SecurityManager sm = System.getSecurityManager(); |
1771 if (sm != null) { |
1770 if (sm != null) { |
1772 checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); |
1771 checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true); |
1773 } |
1772 } |
1774 return copyFields(privateGetPublicFields(null)); |
1773 return copyFields(privateGetPublicFields()); |
1775 } |
1774 } |
1776 |
1775 |
1777 |
1776 |
1778 /** |
1777 /** |
1779 * Returns an array containing {@code Method} objects reflecting all the |
1778 * Returns an array containing {@code Method} objects reflecting all the |
3024 } |
3023 } |
3025 |
3024 |
3026 // Returns an array of "root" fields. These Field objects must NOT |
3025 // Returns an array of "root" fields. These Field objects must NOT |
3027 // be propagated to the outside world, but must instead be copied |
3026 // be propagated to the outside world, but must instead be copied |
3028 // via ReflectionFactory.copyField. |
3027 // via ReflectionFactory.copyField. |
3029 private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) { |
3028 private Field[] privateGetPublicFields() { |
3030 Field[] res; |
3029 Field[] res; |
3031 ReflectionData<T> rd = reflectionData(); |
3030 ReflectionData<T> rd = reflectionData(); |
3032 if (rd != null) { |
3031 if (rd != null) { |
3033 res = rd.publicFields; |
3032 res = rd.publicFields; |
3034 if (res != null) return res; |
3033 if (res != null) return res; |
3035 } |
3034 } |
3036 |
3035 |
3037 // No cached value available; compute value recursively. |
3036 // Use a linked hash set to ensure order is preserved and |
3038 // Traverse in correct order for getField(). |
3037 // fields from common super interfaces are not duplicated |
3039 List<Field> fields = new ArrayList<>(); |
3038 LinkedHashSet<Field> fields = new LinkedHashSet<>(); |
3040 if (traversedInterfaces == null) { |
|
3041 traversedInterfaces = new HashSet<>(); |
|
3042 } |
|
3043 |
3039 |
3044 // Local fields |
3040 // Local fields |
3045 Field[] tmp = privateGetDeclaredFields(true); |
3041 addAll(fields, privateGetDeclaredFields(true)); |
3046 addAll(fields, tmp); |
|
3047 |
3042 |
3048 // Direct superinterfaces, recursively |
3043 // Direct superinterfaces, recursively |
3049 for (Class<?> c : getInterfaces()) { |
3044 for (Class<?> si : getInterfaces()) { |
3050 if (!traversedInterfaces.contains(c)) { |
3045 addAll(fields, si.privateGetPublicFields()); |
3051 traversedInterfaces.add(c); |
|
3052 addAll(fields, c.privateGetPublicFields(traversedInterfaces)); |
|
3053 } |
|
3054 } |
3046 } |
3055 |
3047 |
3056 // Direct superclass, recursively |
3048 // Direct superclass, recursively |
3057 if (!isInterface()) { |
3049 Class<?> sc = getSuperclass(); |
3058 Class<?> c = getSuperclass(); |
3050 if (sc != null) { |
3059 if (c != null) { |
3051 addAll(fields, sc.privateGetPublicFields()); |
3060 addAll(fields, c.privateGetPublicFields(traversedInterfaces)); |
3052 } |
3061 } |
3053 |
3062 } |
3054 res = fields.toArray(new Field[0]); |
3063 |
|
3064 res = new Field[fields.size()]; |
|
3065 fields.toArray(res); |
|
3066 if (rd != null) { |
3055 if (rd != null) { |
3067 rd.publicFields = res; |
3056 rd.publicFields = res; |
3068 } |
3057 } |
3069 return res; |
3058 return res; |
3070 } |
3059 } |