Java 基元泛型方法
我有一个非常有创意的解决方案,允许我的未签名代码通过我的签名库进行所有访问。虽然做法不好,但我担心我没有其他解决方案(除了重写大量代码,然后需要重写回来)。
我有以下类:
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;
}
}
它非常适合返回对象的函数,但不适用于基元。 布尔 bool = full.access(..); 将导致空指针,因为泛型方法无法处理基元。
关于如何采取正确的方法有什么想法吗?
测试:
public static Boolean test() {
return true;
}
public Main() {
System.out.println(((Boolean)redirect.full.access(this, "test", null)));
}
I have a very creative solution to allow my unsigned code all access through my signed library. Although bad practice, I fear I have no other solution (except rewriting a lot of code, that then needs to be rewrited back).
I have the following class:
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;
}
}
It works great for functions that return Objects, but not for primitives.
Boolean bool = full.access(..);
will result in a nullpointer, because generic methods can't handle primitives.
Any ideas about how to take the right approach?
To test:
public static Boolean test() {
return true;
}
public Main() {
System.out.println(((Boolean)redirect.full.access(this, "test", null)));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您收到
NullPointerException
的原因是您始终返回null
。您调用doPrivileged(...)
,但仍返回null
。尝试返回doPrivileged(...)
的输出。从表面上看,自动(取消)装箱在输入和返回的输出上都起作用。这对我有用(我传入了一个原始 int,并期望一个原始布尔值):
另一方面,您可以使其更加健壮。当我传入
Integer
而不是Object
时,找不到 equals 方法,即使它是有效的方法调用。如果您没有找到给定Class
的方法,您应该再次检查该类的父类。The reason you are getting a
NullPointerException
is because you are always returningnull
. You calldoPrivileged(...)
, yetnull
is still returned. Try returning the output ofdoPrivileged(...)
. By the looks of things, Auto(un)boxing is working here on both the inputs and the returned outputs.This worked for me (I passed in a primitive int, and expected a primitive boolean):
On another note, you could make this more robust. When I passed in an
Integer
instead of anObject
, the equals method was not found, even though it would have been a valid method call. If you do not find the method with the givenClass
, you should check again with the classes' parent classes.这不就是原始类的用途吗? (布尔值、整数...)我不确定他们是否会这样做,我还没有检查过。
长答案:克隆所有这些方法以返回原语。
或者更短;您可以将所需的原始类型包装在一个对象中,即执行以下操作:
Isn't that what the primitive classes are for? ( Boolean, Integer... ) I'm not sure if they'll do it, I haven't checked.
Long answer : make a clone of all those methods to return primitives.
Or much shorter; you could just wrap the primitive type you want in an object, that is do something like: