java Reflection.java
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Reflection.java相关的知识,希望对你有一定的参考价值。
/**
* * An utility class that simplifies reflection in Bukkit plugins. * * @author
* Kristian -
* https://github.com/dmulloy2/ProtocolLib/blob/master/Examples/TinyProtocol
* /src/main/java/com/comphenix/tinyprotocol/Reflection.java
*/
public final class Reflection {
public interface ConstructorInvoker {
public Object invoke(Object... arguments);
}
public interface MethodInvoker {
public Object invoke(Object target, Object... arguments);
}
public interface FieldAccessor<T> {
public T get(Object target);
public void set(Object target, Object value);
public boolean hasField(Object target);
}
private static String OBC_PREFIX = Bukkit.getServer().getClass()
.getPackage().getName();
private static String NMS_PREFIX = OBC_PREFIX.replace(
"org.bukkit.craftbukkit", "net.minecraft.server");
private static String VERSION = OBC_PREFIX.replace(
"org.bukkit.craftbukkit", "").replace(".", "");
private static Pattern MATCH_VARIABLE = Pattern.compile("\\{([^\\}]+)\\}");
private Reflection() {
}
public static <T> FieldAccessor<T> getField(Class<?> target, String name,
Class<T> fieldType) {
return getField(target, name, fieldType, 0);
}
public static <T> FieldAccessor<T> getField(String className, String name,
Class<T> fieldType) {
return getField(getClass(className), name, fieldType, 0);
}
public static <T> FieldAccessor<T> getField(Class<?> target,
Class<T> fieldType, int index) {
return getField(target, null, fieldType, index);
}
public static <T> FieldAccessor<T> getField(String className,
Class<T> fieldType, int index) {
return getField(getClass(className), fieldType, index);
}
private static <T> FieldAccessor<T> getField(Class<?> target, String name,
Class<T> fieldType, int index) {
for (final Field field : target.getDeclaredFields()) {
if ((name == null || field.getName().equals(name))
&& fieldType.isAssignableFrom(field.getType())
&& index-- <= 0) {
field.setAccessible(true);
return new FieldAccessor<T>() {
@Override
@SuppressWarnings("unchecked")
public T get(Object target) {
try {
return (T) field.get(target);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Cannot access reflection.", e);
}
}
@Override
public void set(Object target, Object value) {
try {
field.set(target, value);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Cannot access reflection.", e);
}
}
@Override
public boolean hasField(Object target) {
return field.getDeclaringClass().isAssignableFrom(
target.getClass());
}
};
}
}
if (target.getSuperclass() != null)
return getField(target.getSuperclass(), name, fieldType, index);
throw new IllegalArgumentException("Cannot find field with type "
+ fieldType);
}
public static MethodInvoker getMethod(String className, String methodName,
Class<?>... params) {
return getTypedMethod(getClass(className), methodName, null, params);
}
public static MethodInvoker getMethod(Class<?> clazz, String methodName,
Class<?>... params) {
return getTypedMethod(clazz, methodName, null, params);
}
public static MethodInvoker getTypedMethod(Class<?> clazz,
String methodName, Class<?> returnType, Class<?>... params) {
for (final Method method : clazz.getDeclaredMethods()) {
if ((methodName == null || method.getName().equals(methodName))
&& (returnType == null)
|| method.getReturnType().equals(returnType)
&& Arrays.equals(method.getParameterTypes(), params)) {
method.setAccessible(true);
return new MethodInvoker() {
@Override
public Object invoke(Object target, Object... arguments) {
try {
return method.invoke(target, arguments);
} catch (Exception e) {
throw new RuntimeException("Cannot invoke method "
+ method, e);
}
}
};
}
}
if (clazz.getSuperclass() != null)
return getMethod(clazz.getSuperclass(), methodName, params);
throw new IllegalStateException(String.format(
"Unable to find method %s (%s).", methodName,
Arrays.asList(params)));
}
public static ConstructorInvoker getConstructor(String className,
Class<?>... params) {
return getConstructor(getClass(className), params);
}
public static ConstructorInvoker getConstructor(Class<?> clazz,
Class<?>... params) {
for (final Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (Arrays.equals(constructor.getParameterTypes(), params)) {
constructor.setAccessible(true);
return new ConstructorInvoker() {
@Override
public Object invoke(Object... arguments) {
try {
return constructor.newInstance(arguments);
} catch (Exception e) {
throw new RuntimeException(
"Cannot invoke constructor " + constructor,
e);
}
}
};
}
}
throw new IllegalStateException(String.format(
"Unable to find constructor for %s (%s).", clazz,
Arrays.asList(params)));
}
public static Class<Object> getUntypedClass(String lookupName) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Class<Object> clazz = (Class) getClass(lookupName);
return clazz;
}
public static Class<?> getClass(String lookupName) {
return getCanonicalClass(expandVariables(lookupName));
}
public static Class<?> getNewClass(String lookupName) {
return getCanonicalClass(lookupName);
}
public static Class<?> getMinecraftClass(String name) {
return getCanonicalClass(NMS_PREFIX + "." + name);
}
public static Class<?> getCraftBukkitClass(String name) {
return getCanonicalClass(OBC_PREFIX + "." + name);
}
private static Class<?> getCanonicalClass(String canonicalName) {
try {
return Class.forName(canonicalName);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Cannot find " + canonicalName,
e);
}
}
private static String expandVariables(String name) {
StringBuffer output = new StringBuffer();
Matcher matcher = MATCH_VARIABLE.matcher(name);
while (matcher.find()) {
String variable = matcher.group(1);
String replacement = "";
if ("nms".equalsIgnoreCase(variable))
replacement = NMS_PREFIX;
else if ("obc".equalsIgnoreCase(variable))
replacement = OBC_PREFIX;
else if ("version".equalsIgnoreCase(variable))
replacement = VERSION;
else
throw new IllegalArgumentException("Unknown variable: "
+ variable);
if (replacement.length() > 0 && matcher.end() < name.length()
&& name.charAt(matcher.end()) != '.')
replacement += ".";
matcher.appendReplacement(output,
Matcher.quoteReplacement(replacement));
}
matcher.appendTail(output);
return output.toString();
}
}
以上是关于java Reflection.java的主要内容,如果未能解决你的问题,请参考以下文章