Fields Summary |
---|
private static final EnumComparator | ENUM_COMPARATORnon-null; comparator used for enumerated values |
static final org.apache.harmony.kernel.vm.ReflectionAccess | REFLECTnon-null; reflection access bridge |
private final Class | clazznon-null; class that this instance represents |
private volatile Method[] | declaredMethodsnull-ok; list of all declared methods |
private volatile Method[] | declaredPublicMethodsnull-ok; list of all public declared methods |
private volatile Method[] | allMethodsnull-ok; list of all methods, both direct and inherited |
private volatile Method[] | allPublicMethodsnull-ok; list of all public methods, both direct and inherited |
private volatile Field[] | declaredFieldsnull-ok; list of all declared fields |
private volatile Field[] | declaredPublicFieldsnull-ok; list of all public declared fields |
private volatile Field[] | allFieldsnull-ok; list of all fields, both direct and inherited |
private volatile Field[] | allPublicFieldsnull-ok; list of all public fields, both direct and inherited |
private volatile T[] | enumValuesInOrdernull-ok; array of enumerated values in their original order, if this
instance's class is an enumeration |
private volatile T[] | enumValuesByNamenull-ok; array of enumerated values sorted by name, if this
instance's class is an enumeration |
Methods Summary |
---|
private T[] | callEnumValues()Calls the static method values() on this
instance's class, which is presumed to be a properly-formed
enumeration class, using proper privilege hygiene.
Method method;
try {
Method[] methods = getDeclaredPublicMethods();
method = findMethodByName(methods, "values", (Class[]) null);
method = REFLECT.accessibleClone(method);
} catch (NoSuchMethodException ex) {
// This shouldn't happen if the class is a well-formed enum.
throw new UnsupportedOperationException(ex);
}
try {
return (T[]) method.invoke((Object[]) null);
} catch (IllegalAccessException ex) {
// This shouldn't happen because the method is "accessible."
throw new Error(ex);
} catch (InvocationTargetException ex) {
Throwable te = ex.getTargetException();
if (te instanceof RuntimeException) {
throw (RuntimeException) te;
} else if (te instanceof Error) {
throw (Error) te;
} else {
throw new Error(te);
}
}
|
public static boolean | compareClassLists(java.lang.Class[] a, java.lang.Class[] b)Compares two class lists for equality. Empty and
null lists are considered equal. This is useful
for matching methods and constructors.
TODO: Take into account assignment compatibility?
if (a == null) {
return (b == null) || (b.length == 0);
}
int length = a.length;
if (b == null) {
return (length == 0);
}
if (length != b.length) {
return false;
}
for (int i = length - 1; i >= 0; i--) {
if (a[i] != b[i]) {
return false;
}
}
return true;
|
public static java.lang.reflect.Method[] | deepCopy(java.lang.reflect.Method[] orig)Makes a deep copy of the given array of methods. This is useful
when handing out arrays from the public API.
Note: In such cases, it is insufficient to just make
a shallow copy of the array, since method objects aren't
immutable due to the existence of {@link
AccessibleObject#setAccessible}.
int length = orig.length;
Method[] result = new Method[length];
for (int i = length - 1; i >= 0; i--) {
result[i] = REFLECT.clone(orig[i]);
}
return result;
|
public static java.lang.reflect.Field[] | deepCopy(java.lang.reflect.Field[] orig)Makes a deep copy of the given array of fields. This is useful
when handing out arrays from the public API.
Note: In such cases, it is insufficient to just make
a shallow copy of the array, since field objects aren't
immutable due to the existence of {@link
AccessibleObject#setAccessible}.
int length = orig.length;
Field[] result = new Field[length];
for (int i = length - 1; i >= 0; i--) {
result[i] = REFLECT.clone(orig[i]);
}
return result;
|
private static void | findAllMethods(java.lang.Class clazz, java.util.ArrayList methods, java.util.HashSet seen, boolean publicOnly)Collects the list of methods without performing any security checks
first. This includes the methods inherited from superclasses and from
all implemented interfaces. The latter may also implement multiple
interfaces, so we (potentially) recursively walk through a whole tree of
classes. If no methods exist at all, an empty array is returned.
StringBuilder builder = new StringBuilder();
Class<?> origClass = clazz;
// Traverse class and superclasses, get rid of dupes by signature
while (clazz != null) {
Method[] declaredMethods =
clazz.getClassCache().getDeclaredMethods(publicOnly);
int length = declaredMethods.length;
if (length != 0) {
for (Method method : declaredMethods) {
builder.setLength(0);
builder.append(method.getName());
builder.append('(");
Class<?>[] types = method.getParameterTypes();
if (types.length != 0) {
builder.append(types[0].getName());
for (int j = 1; j < types.length; j++) {
builder.append(',");
builder.append(types[j].getName());
}
}
builder.append(')");
String signature = builder.toString();
if (!seen.contains(signature)) {
methods.add(method);
seen.add(signature);
}
}
}
clazz = clazz.getSuperclass();
}
// Traverse all interfaces, and do the same recursively.
Class<?>[] interfaces = origClass.getInterfaces();
for (Class<?> intf : interfaces) {
findAllMethods(intf, methods, seen, publicOnly);
}
|
private static void | findAllfields(java.lang.Class clazz, java.util.ArrayList fields, java.util.HashSet seen, boolean publicOnly)Collects the list of fields without performing any security checks
first. This includes the fields inherited from superclasses and from
all implemented interfaces. The latter may also implement multiple
interfaces, so we (potentially) recursively walk through a whole tree of
classes. If no fields exist at all, an empty array is returned.
// Traverse class and superclasses, get rid of dupes by signature
while (clazz != null) {
Field[] declaredFields =
clazz.getClassCache().getDeclaredFields(publicOnly);
for (Field field : declaredFields) {
String signature = field.toString();
if (!seen.contains(signature)) {
fields.add(field);
seen.add(signature);
}
}
// Traverse all interfaces, and do the same recursively.
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> intf : interfaces) {
findAllfields(intf, fields, seen, publicOnly);
}
clazz = clazz.getSuperclass();
}
|
public static java.lang.reflect.Field | findFieldByName(java.lang.reflect.Field[] list, java.lang.String name)Finds and returns a field with a given name and signature. Use
this with one of the field lists returned by instances of this class.
if (name == null) {
throw new NullPointerException("Field name must not be null.");
}
for (int i = 0; i < list.length; i++) {
Field field = list[i];
if (field.getName().equals(name)) {
return field;
}
}
throw new NoSuchFieldException(name);
|
public static java.lang.reflect.Method | findMethodByName(java.lang.reflect.Method[] list, java.lang.String name, java.lang.Class[] parameterTypes)Finds and returns a method with a given name and signature. Use
this with one of the method lists returned by instances of this class.
if (name == null) {
throw new NullPointerException("Method name must not be null.");
}
for (int i = list.length - 1; i >= 0; i--) {
Method method = list[i];
if (method.getName().equals(name)
&& compareClassLists(
method.getParameterTypes(), parameterTypes)) {
return method;
}
}
throw new NoSuchMethodException(name);
|
public java.lang.reflect.Field[] | getAllFields()Gets the list of all fields, both directly
declared and inherited.
if (allFields == null) {
allFields = getFullListOfFields(false);
}
return allFields;
|
public java.lang.reflect.Method[] | getAllMethods()Gets the list of all methods, both directly
declared and inherited.
if (allMethods == null) {
allMethods = getFullListOfMethods(false);
}
return allMethods;
|
public java.lang.reflect.Field[] | getAllPublicFields()Gets the list of all public fields, both directly
declared and inherited.
if (allPublicFields == null) {
allPublicFields = getFullListOfFields(true);
}
return allPublicFields;
|
public java.lang.reflect.Method[] | getAllPublicMethods()Gets the list of all public methods, both directly
declared and inherited.
if (allPublicMethods == null) {
allPublicMethods = getFullListOfMethods(true);
}
return allPublicMethods;
|
public java.lang.reflect.Field[] | getDeclaredFields()Gets the list of all declared fields.
if (declaredFields == null) {
declaredFields = Class.getDeclaredFields(clazz, false);
}
return declaredFields;
|
public java.lang.reflect.Field[] | getDeclaredFields(boolean publicOnly)Gets either the list of declared fields or the list of declared
public fields.
return publicOnly ? getDeclaredPublicFields() : getDeclaredFields();
|
public java.lang.reflect.Method[] | getDeclaredMethods()Gets the list of all declared methods.
if (declaredMethods == null) {
declaredMethods = Class.getDeclaredMethods(clazz, false);
}
return declaredMethods;
|
public java.lang.reflect.Method[] | getDeclaredMethods(boolean publicOnly)Gets either the list of declared methods or the list of declared
public methods.
return publicOnly ? getDeclaredPublicMethods() : getDeclaredMethods();
|
public java.lang.reflect.Field[] | getDeclaredPublicFields()Gets the list of all declared public fields.
if (declaredPublicFields == null) {
declaredPublicFields = Class.getDeclaredFields(clazz, true);
}
return declaredPublicFields;
|
public java.lang.reflect.Method[] | getDeclaredPublicMethods()Gets the list of all declared public methods.
if (declaredPublicMethods == null) {
declaredPublicMethods = Class.getDeclaredMethods(clazz, true);
}
return declaredPublicMethods;
|
public T | getEnumValue(java.lang.String name)Gets the enumerated value with a given name.
Enum[] values = (Enum[]) getEnumValuesByName();
if (values == null) {
return null;
}
// Binary search.
int min = 0;
int max = values.length - 1;
while (min <= max) {
/*
* The guessIdx calculation is equivalent to ((min + max)
* / 2) but won't go wonky when min and max are close to
* Integer.MAX_VALUE.
*/
int guessIdx = min + ((max - min) >> 1);
Enum guess = values[guessIdx];
int cmp = name.compareTo(guess.name());
if (cmp < 0) {
max = guessIdx - 1;
} else if (cmp > 0) {
min = guessIdx + 1;
} else {
return (T) guess;
}
}
return null;
|
public T[] | getEnumValuesByName()Gets the array of enumerated values, sorted by name.
if (enumValuesByName == null) {
T[] values = getEnumValuesInOrder();
if (values != null) {
values = (T[]) values.clone();
Arrays.sort((Enum<?>[]) values, ENUM_COMPARATOR);
/*
* Note: It's only safe (concurrency-wise) to set the
* instance variable after the array is properly sorted.
*/
enumValuesByName = values;
}
}
return enumValuesByName;
|
public T[] | getEnumValuesInOrder()Gets the array of enumerated values, in their original declared
order.
if ((enumValuesInOrder == null) && clazz.isEnum()) {
enumValuesInOrder = callEnumValues();
}
return enumValuesInOrder;
|
private java.lang.reflect.Field[] | getFullListOfFields(boolean publicOnly)
ArrayList<Field> fields = new ArrayList<Field>();
HashSet<String> seen = new HashSet<String>();
findAllfields(clazz, fields, seen, publicOnly);
return fields.toArray(new Field[fields.size()]);
|
private java.lang.reflect.Method[] | getFullListOfMethods(boolean publicOnly)
ArrayList<Method> methods = new ArrayList<Method>();
HashSet<String> seen = new HashSet<String>();
findAllMethods(clazz, methods, seen, publicOnly);
return methods.toArray(new Method[methods.size()]);
|
private static org.apache.harmony.kernel.vm.ReflectionAccess | getReflectionAccess()Gets the reflection access object. This uses reflection to do
so. My head is spinning.
/*
* Note: We can't do AccessibleObject.class.getCache() to
* get the cache, since that would cause a circularity in
* initialization. So instead, we do a direct call into the
* native side.
*/
Method[] methods =
Class.getDeclaredMethods(AccessibleObject.class, false);
try {
Method method = findMethodByName(methods, "getReflectionAccess",
(Class[]) null);
Class.setAccessibleNoCheck(method, true);
return (ReflectionAccess) method.invoke((Object[]) null);
} catch (NoSuchMethodException ex) {
/*
* This shouldn't happen because the method
* AccessibleObject.getReflectionAccess() really is defined
* in this module.
*/
throw new Error(ex);
} catch (IllegalAccessException ex) {
// This shouldn't happen because the method is "accessible."
throw new Error(ex);
} catch (InvocationTargetException ex) {
throw new Error(ex);
}
|