Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
验证Java中反射的方法返回类型和参数_Java_Reflection_Types_Closures_Callback - Fatal编程技术网

验证Java中反射的方法返回类型和参数

验证Java中反射的方法返回类型和参数,java,reflection,types,closures,callback,Java,Reflection,Types,Closures,Callback,我有一个通用回调对象,它在没有闭包的情况下为Java提供(基本的)回调功能。回调对象包含一个方法,并通过两个访问器方法返回该方法的参数和返回类型,这些方法只是委托给方法中的等效方法 我试图验证提供给我的回调是否指向有效的方法。我需要返回类型赋值与Number兼容,所有参数赋值与Double兼容。我的验证方法如下所示: static public void checkFunctionSpec(Callback cbk) { Class[]

我有一个通用回调对象,它在没有闭包的情况下为Java提供(基本的)回调功能。回调对象包含一个方法,并通过两个访问器方法返回该方法的参数和返回类型,这些方法只是委托给方法中的等效方法

我试图验证提供给我的回调是否指向有效的方法。我需要返回类型赋值与Number兼容,所有参数赋值与Double兼容。我的验证方法如下所示:

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));
}