我有一个非常有创意的解决方案,允许我的未签名代码通过我签名的库进行访问。虽然做法不好,但我担心我没有其他解决方案(除了重写大量代码,然后需要重新编写代码)。
我有以下课程:
public abstract class full {
public static <T,S,P> S access(final T object, final String function, final P parameter) {
AccessController.doPrivileged(new PrivilegedAction<S>() {
@Override
public S run() {
try {
if (parameter == null) {
Class[] argTypes = { };
Object passedArgv[] = { };
return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
} else {
Class[] argTypes = { parameter.getClass() };
Object passedArgv[] = { parameter };
return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
}
} catch (NoSuchMethodException ex) {
Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
});
return null;
}
}
它适用于返回Objects的函数,但不适用于基元。 Boolean bool = full.access(..); 将导致nullpointer,因为泛型方法无法处理原语。
关于如何采取正确方法的任何想法?
测试:
public static Boolean test() {
return true;
}
public Main() {
System.out.println(((Boolean)redirect.full.access(this, "test", null)));
}
答案 0 :(得分:1)
这不是原始类的用途吗? (布尔值,整数......)我不确定他们是否会这样做,我没有检查过。
长答案:克隆所有这些方法以返回原语。
或者更短;你可以将你想要的基本类型包装在一个对象中,就像这样:
public class MyInt {
public int intValue;
}
答案 1 :(得分:1)
您获得NullPointerException
的原因是因为您总是返回null
。您致电doPrivileged(...)
,但仍然会返回null
。尝试返回doPrivileged(...)
的输出。根据事物的外观,Auto(un)装箱在输入和返回的输出上工作。
这对我有用(我传入一个原始的int,并期望一个原始的布尔值):
public class ATest
{
public static void main(String[] args) throws UnsupportedEncodingException
{
int i = 5;
Object equals = new Object();
boolean b = full.access(i, "equals", equals);
System.out.println(b);
}
public static class full
{
public static <T, S, P> S access(final T object, final String function, final P parameter)
{
return AccessController.doPrivileged(new PrivilegedAction<S>()
{
@Override
public S run()
{
try
{
if (parameter == null)
{
Class[] argTypes = {};
Object passedArgv[] = {};
return (S) object.getClass().getMethod(function, argTypes)
.invoke(object, passedArgv);
}
else
{
Class[] argTypes = { parameter.getClass() };
Object passedArgv[] = { parameter };
return (S) object.getClass().getMethod(function, argTypes)
.invoke(object, passedArgv);
}
}
catch (NoSuchMethodException ex)
{
Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
}
catch (SecurityException ex)
{
Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
}
catch (InvocationTargetException ex)
{
Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
}
return null;
}
});
}
}
}
另一方面,你可以让它更健壮。当我传入Integer
而不是Object
时,找不到equals方法,即使它是一个有效的方法调用。如果您没有找到具有给定Class
的方法,则应该再次检查类的父类。