验证Java中反射的方法返回类型和参数
我有一个通用回调对象,它在没有闭包的情况下为Java提供(基本的)回调功能。回调对象包含一个方法,并通过两个访问器方法返回该方法的参数和返回类型,这些方法只是委托给方法中的等效方法 我试图验证提供给我的回调是否指向有效的方法。我需要返回类型赋值与Number兼容,所有参数赋值与Double兼容。我的验证方法如下所示:验证Java中反射的方法返回类型和参数,java,reflection,types,closures,callback,Java,Reflection,Types,Closures,Callback,我有一个通用回调对象,它在没有闭包的情况下为Java提供(基本的)回调功能。回调对象包含一个方法,并通过两个访问器方法返回该方法的参数和返回类型,这些方法只是委托给方法中的等效方法 我试图验证提供给我的回调是否指向有效的方法。我需要返回类型赋值与Number兼容,所有参数赋值与Double兼容。我的验证方法如下所示: static public void checkFunctionSpec(Callback cbk) { Class[]
static public void checkFunctionSpec(Callback cbk) {
Class[] prms=cbk.getParmTypes();
Class ret =cbk.getReturnType();
if(!Number.class.isAssignableFrom(ret)) {
throw new IllegalArgumentException(
"A function callback must return a Number type " +
"(any Number object or numeric primitive) - function '" +
cbk + "' is not permitted");
}
for(Class prm: prms) {
if(!Double.class.isAssignableFrom(prm)) {
throw new IllegalArgumentException(
"A function callback must take parameters of " +
"assignment compatible with double " +
"(a Double or Float object or a double or float primitive) " +
"- function '" + cbk + "' is not permitted");
}
}
}
我遇到的问题是,当我尝试使用Math.abs()时,它会为返回类型抛出一个异常,如下所示:
java.lang.IllegalArgumentException:
A function callback must return a Number type (any Number object or numeric primitive)
- function 'public static double java.lang.Math.abs(double)' is not permitted
这让我感到惊讶,因为我希望原语能够简单地工作,因为(a)它们是使用包装器类反映的,(b)Double.TYPE被声明为Class类型
有人知道我如何在不修改支票的情况下实现这一点吗
if(!Number.class.isAssignableFrom(ret)
&& ret!=Double.TYPE
&& ret!=Float.TYPE
&& ret!=...) {
澄清 使用method.invoke()调用方法
double abs(double)
时,传入一个对象[]{double},并返回一个double。但是,我的验证似乎失败了,因为Double.TYPE不可分配给Double。由于我要求所有这些回调都返回某种数字,invoke()会将其作为数字返回,因此我尝试验证提供的方法是否返回数字或数字原语
parms的验证也是如此
换句话说,当使用反射时,parm和返回类型Double和Double是相同的,我想简单地验证它们
编辑:为了进一步澄清:我想验证调用invoke()时,方法是否会返回一个Number类型的对象(我可以从中调用obj.doubleValue()来获取我想要的double)。为什么不让编译器执行此操作
public interface F<A, B> {
public B $(A a);
}
在这种情况下,您可以实现一个函数类型:
public interface F<A extends L<A>, B> {
public B $(A args);
}
F
接口的实现必须使用head
和tail
从列表中获取参数。实际上,您正在用Java实现LISP
话虽如此,还是去看看吧,这是一个已经有很多这种东西的图书馆。我确信还有一个使用反射的,这样你就不必自己写了。Math.abs()的参数是double原语。我不太清楚您所说的原语与对象“赋值兼容”是什么意思(反射API本质上的意思是“可以是对象的类型转换”)。但如果你的意思是“可以传递到一个双构造函数”,那么这本质上就是一个基本的双(或字符串)!!也许您需要进一步澄清一下您需要做什么?仔细查看Class.isAssignableFrom()的文档,它特别指出基元的类型与除它们自身之外的任何类都不匹配。因此,我需要特别检查返回类型的==与Byte.TYPE、Double.TYPE、Float.TYPE、Integer.TYPE、Long.TYPE和Short.TYPE的相等性。部分原因是这些回调是可公开注册的回调,我不想为1个parm、2个parm等创建接口,直到10个parm。这在很大程度上也是因为它们也会有原始回报。一个接口无法捕获该本质。另外,因为我希望一个类能够为任意数量的方法提供回调,而不是强制调用的每个方法位于单独的类中(请不要说我应该使用匿名类)。一个接口可以捕获该本质,但您可能会发现它过于繁琐。请参见最后一次编辑。匿名课程有什么问题吗?不,这根本不是我要问的。我想验证调用invoke时,方法是否会返回一个Number类型的对象(我可以从中调用obj.doubleValue()来获得我想要的double)。
public Double operate(F<Double, F<Double, Double>> f, double a, double b) {
return f.$(a).$(b);
}
public abstract class L<A extends L<A>> {
private L() {}
private static final N nil = new N();
public static N nil() {
return nil;
}
public static final class N extends L<N> {
private N() {}
public <E> C<E, N> cons(final E e) {
return new C<E, L>(e, this);
}
}
public static final class C<E, L extends L<L>> extends L<C<E, L>> {
private E e;
private L l;
private C(final E e, final L l) {
this.e = e;
this.l = l;
}
public E head() {
return e;
}
public L tail() {
return l;
}
public <E> C<E, C<E, L>> cons(final E e) {
return new C<E, C<E, L>>(e, this);
}
}
}
public interface F<A extends L<A>, B> {
public B $(A args);
}
public Double operate(F<C<Double, C<Double, N>>, Double> f, double a, double b) {
return f.$(N.nil().cons(b).cons(a));
}