mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
Implement Field#getGenericType()
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
parent
0eb2d55da2
commit
2d83622975
@ -66,6 +66,14 @@ public class Field<T> extends AccessibleObject {
|
||||
new String(vmField.spec, 0, vmField.spec.length - 1, false));
|
||||
}
|
||||
|
||||
public Type getGenericType() {
|
||||
if (vmField.addendum == null || vmField.addendum.signature == null) {
|
||||
return getType();
|
||||
}
|
||||
String signature = Classes.toString((byte[]) vmField.addendum.signature);
|
||||
return SignatureParser.parse(vmField.class_.loader, signature);
|
||||
}
|
||||
|
||||
public Object get(Object instance) throws IllegalAccessException {
|
||||
Object target;
|
||||
if ((vmField.flags & Modifier.STATIC) != 0) {
|
||||
|
17
classpath/java/lang/reflect/ParameterizedType.java
Normal file
17
classpath/java/lang/reflect/ParameterizedType.java
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
public interface ParameterizedType extends Type {
|
||||
Type[] getActualTypeArguments();
|
||||
Type getOwnerType();
|
||||
Type getRawType();
|
||||
}
|
135
classpath/java/lang/reflect/SignatureParser.java
Normal file
135
classpath/java/lang/reflect/SignatureParser.java
Normal file
@ -0,0 +1,135 @@
|
||||
/* Copyright (c) 2008-2013, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class SignatureParser {
|
||||
private final ClassLoader loader;
|
||||
private final char[] array;
|
||||
private int offset;
|
||||
private final Type type;
|
||||
|
||||
static Type parse(ClassLoader loader, String signature) {
|
||||
return new SignatureParser(loader, signature).type;
|
||||
}
|
||||
|
||||
private SignatureParser(ClassLoader loader, String signature) {
|
||||
this.loader = loader;
|
||||
array = signature.toCharArray();
|
||||
type = parseType();
|
||||
if (offset != array.length) {
|
||||
throw new IllegalArgumentException("Extra characters after " + offset
|
||||
+ ": " + signature);
|
||||
}
|
||||
}
|
||||
|
||||
private Type parseType() {
|
||||
char c = array[offset++];
|
||||
if (c == 'B') {
|
||||
return Byte.TYPE;
|
||||
} else if (c == 'C') {
|
||||
return Character.TYPE;
|
||||
} else if (c == 'D') {
|
||||
return Double.TYPE;
|
||||
} else if (c == 'F') {
|
||||
return Float.TYPE;
|
||||
} else if (c == 'I') {
|
||||
return Integer.TYPE;
|
||||
} else if (c == 'J') {
|
||||
return Long.TYPE;
|
||||
} else if (c == 'S') {
|
||||
return Short.TYPE;
|
||||
} else if (c == 'Z') {
|
||||
return Boolean.TYPE;
|
||||
} else if (c != 'L') {
|
||||
throw new IllegalArgumentException("Unexpected character: " + c);
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Type ownerType = null;
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
c = array[offset++];
|
||||
if (c == ';' || c == '<') {
|
||||
break;
|
||||
}
|
||||
builder.append(c == '/' ? '.' : c);
|
||||
}
|
||||
String rawTypeName = builder.toString();
|
||||
Class<?> rawType;
|
||||
try {
|
||||
rawType = loader.loadClass(rawTypeName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Could not find class " + rawTypeName);
|
||||
}
|
||||
if (c == ';') {
|
||||
return rawType;
|
||||
}
|
||||
List<Type> args = new ArrayList<Type>();
|
||||
while (array[offset] != '>') {
|
||||
args.add(parseType());
|
||||
}
|
||||
++offset;
|
||||
c = array[offset++];
|
||||
ParameterizedType type = makeType(args.toArray(new Type[args.size()]), ownerType, rawType);
|
||||
if (c == ';') {
|
||||
return type;
|
||||
}
|
||||
if (c != '.') {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
ownerType = type;
|
||||
builder.append("$");
|
||||
}
|
||||
}
|
||||
|
||||
private static String typeName(Type type) {
|
||||
if (type instanceof Class) {
|
||||
Class<?> clazz = (Class<?>) type;
|
||||
return clazz.getName();
|
||||
}
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
private static ParameterizedType makeType(final Type[] args, final Type owner, final Type raw) {
|
||||
return new ParameterizedType() {
|
||||
@Override
|
||||
public Type getRawType() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(typeName(raw));
|
||||
builder.append('<');
|
||||
String sep = "";
|
||||
for (Type t : args) {
|
||||
builder.append(sep).append(typeName(t));
|
||||
sep = ", ";
|
||||
}
|
||||
builder.append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class Reflection {
|
||||
public static boolean booleanMethod() {
|
||||
@ -38,8 +40,8 @@ public class Reflection {
|
||||
if (! v) throw new RuntimeException();
|
||||
}
|
||||
|
||||
private static class Hello {
|
||||
private class World { }
|
||||
private static class Hello<T> {
|
||||
private class World<S> { }
|
||||
}
|
||||
|
||||
private static void innerClasses() throws Exception {
|
||||
@ -56,9 +58,44 @@ public class Reflection {
|
||||
expect(egads.getAnnotation(Deprecated.class) == null);
|
||||
}
|
||||
|
||||
public static Hello<Hello<Reflection>>.World<Hello<String>> pinky;
|
||||
|
||||
private static void genericType() throws Exception {
|
||||
Field field = Reflection.class.getDeclaredField("egads");
|
||||
expect(field.getGenericType() == Integer.TYPE);
|
||||
|
||||
field = Reflection.class.getField("pinky");
|
||||
expect("Reflection$Hello$World".equals(field.getType().getName()));
|
||||
expect(field.getGenericType() instanceof ParameterizedType);
|
||||
ParameterizedType type = (ParameterizedType) field.getGenericType();
|
||||
|
||||
expect(type.getRawType() instanceof Class);
|
||||
Class<?> clazz = (Class<?>) type.getRawType();
|
||||
expect("Reflection$Hello$World".equals(clazz.getName()));
|
||||
|
||||
expect(type.getOwnerType() instanceof ParameterizedType);
|
||||
ParameterizedType owner = (ParameterizedType) type.getOwnerType();
|
||||
clazz = (Class<?>) owner.getRawType();
|
||||
expect(clazz == Hello.class);
|
||||
|
||||
Type[] args = type.getActualTypeArguments();
|
||||
expect(1 == args.length);
|
||||
expect(args[0] instanceof ParameterizedType);
|
||||
|
||||
ParameterizedType arg = (ParameterizedType) args[0];
|
||||
expect(arg.getRawType() instanceof Class);
|
||||
clazz = (Class<?>) arg.getRawType();
|
||||
expect("Reflection$Hello".equals(clazz.getName()));
|
||||
|
||||
args = arg.getActualTypeArguments();
|
||||
expect(1 == args.length);
|
||||
expect(args[0] == String.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
innerClasses();
|
||||
annotations();
|
||||
genericType();
|
||||
|
||||
Class system = Class.forName("java.lang.System");
|
||||
Field out = system.getDeclaredField("out");
|
||||
|
Loading…
Reference in New Issue
Block a user