문제

폐쇄가없는 상태에서 Java에 대한 (원시적) 콜백 기능을 제공하는 일반적인 콜백 객체가 있습니다. 콜백 객체에는 메소드가 포함되어 있으며 메소드의 동등한 메소드를 위임하는 몇 개의 액세서 메소드를 통해 메소드의 매개 변수 및 리턴 유형을 반환합니다.

공급 된 콜백이 유효한 방법을 가리키는 것을 확인하려고합니다. 숫자와 호환되는 리턴 유형 할당이 필요합니다. 내 검증 방법은 다음과 같습니다.

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가 유형 클래스로 선언되기 때문에 프리미티브가 단순히 작동 할 것으로 예상했기 때문에 놀랍습니다.u003CDouble> .

누구든지 수표를 수정하지 않고이 작업을 달성 할 수있는 방법을 알고 있습니까?

if(!Number.class.isAssignableFrom(ret)
     && ret!=Double.TYPE
     && ret!=Float.TYPE
     && ret!=...) {

설명

메소드를 호출 할 때 double abs(double) method.invoke ()를 사용하여 객체 [] {double}을 전달하고 더블을 되돌립니다. 그러나 Double.type가 더블에 할당 할 수 없기 때문에 내 검증이 실패한 것으로 보입니다. 이 모든 콜백은 invoke ()에 의해 숫자로 반환 될 숫자를 반환해야하기 때문에 제공된 메소드가 숫자 또는 숫자 원시를 반환하는지 확인하려고합니다.

PARM의 검증도 마찬가지입니다.

다시 말해, 반사를 사용할 때 Parm과 Return 유형이 더블 및 더블이 동일하며이를 검증하고 싶습니다. 용이하게 따라서.

편집 : 더 명확히하기 위해 : invoke ()를 유형 번호의 객체라고 불렀을 때 메소드가 표시되는지 확인하고 싶습니다 (이중으로 내가 원하는 이중을 얻으려면 obj.doublevalue ()를 호출 할 수 있음).

도움이 되었습니까?

해결책

Class.isAssignableFrom ()의 문서를 더 자세히 살펴보면 프리미티브 유형이 자신을 제외한 클래스와 일치하지 않는다고 명시하고 있습니다. 따라서 Byte.type, double.type, float.type, integer.type, long.type 및 short.

다른 팁

컴파일러가하지 않는 이유는 무엇입니까?

public interface F<A, B> {
   public B $(A a);
}

그런 다음 통과 할 수 있습니다 F<Double, Double> 예상되는 방법에 F<? extends Number, ? extends Number>.

편집하다:

여러 인수가있는 함수 유형에 대해 단일 클래스를 제공하고 싶다고 말합니다. 이것 ~할 수 있다 Java 유형 시스템으로 수행하십시오. 개념적으로 모든 기능에는 하나의 인수 만 있습니다. 두 인수가있는 함수는 다른 함수를 반환하는 함수와 같습니다. 여기에는 값이 두 배의 복식을 취하는 함수 인 변수가 있습니다.

F<Double, F<Double, Double>> f;

다음은 주어진 기능으로 두 개의 복식을 전달하는 방법입니다.

public Double operate(F<Double, F<Double, Double>> f, double a, double b) {
   return f.$(a).$(b);
}

또는 유형을 고려하십시오 L<A extends L> 두 개의 서브 클래스로 C<E, T extends L<T>> "단점"및 터미네이터 유형을 나타냅니다. N:

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

다음 방법은 두 가지 기능을 기대합니다 Double 인수 (그리고 반환 a Double), 두와 함께 doubles에 적용 할 :

public Double operate(F<C<Double, C<Double, N>>, Double> f, double a, double b) {
   return f.$(N.nil().cons(b).cons(a));
}

의 구현 F 인터페이스는 목록에서 인수를 가져와야합니다. head 그리고 tail. 사실상, 당신은 Java에서 LISP를 구현하고 있습니다. :)

그렇게 말하면서 확인하십시오 기능적 자바, 이것은 이미 많은 것을 가지고있는 도서관입니다. 반사를 사용하는 것이 있다고 확신하므로 직접 쓸 필요가 없습니다.

Math.abs ()의 매개 변수는 이중 원시입니다. 나는 객체와 함께 "할당 호환"라는 원시가 무엇을 의미하는지 잘 모르겠습니다 (반사 API가 본질적으로 의미하는 것은 "캐스트가 될 수 있음"). 그러나 "이중 생성자로 전달 될 수있다"는 의미가 있다면, 그것은 본질적으로 원시 이중 (또는 문자열)입니다! 아마도 당신은 당신이해야 할 일을 조금 더 명확히해야합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top