2014-05-20 3 views
1

내 DTO 개체 중 하나가 실제로 nullable 속성을 가질 수 있도록 JSNI 메서드 반환 형식을 고민하고 있습니다. 문서 당으로GWT, JSNI : 완전 nullable 메소드로 오버레이 객체 구현?

public class Dto extends JavaScriptObject { 

    protected Dto() { 
    } 

    private native Integer getValue1() /*-{ return this.value1; }-*/; 

    // no longs are allowed 
    private native Double getValue2() /*-{ return this.value2; }-*/; 

    // TODO migrate to Java 8 
    public static final Function<Dto, DomainObject> dtoToDomainObject = new Function<Dto, DomainObject>() { 
     @Override 
     public DomainObject apply(Dto dto) { 
      return new DomainObject(
        dto.getValue1(), 
        (long) dto.getValue2() 
      ); 
     } 
    }; 

} 

, 발신 유형은 단지 String, boolean, 자바 숫자 원시적 (일부 제한), JavaScriptObject, Object 및 배열 인 :이 첫 분명히 실패 오버레이 DTO에 대한 시도했다 . 그리고이 제한은 Number 상자를 통해 JavaScript "primitive"를 전달하지 못하게하는 다양한 런타임 예외 때문에 nullable 의미에 맞지 않는 것처럼 보입니다. 이것은 다소 이상하지만, 기술적 인 논점이 있다고 믿습니다. 어쨌든. 지금까지 내 실험을하는 동안 예외를 많이 받고 후, 나는 다음과 같은 방법을 벌었 : 나는 나를 실제 값과 널 (null)을 구별시키는 예상대로 두 번째 구현은 마지막으로 작동

public class Dto extends JavaScriptObject { 

    protected Dto() { 
    } 

    private native boolean hasValue1() /*-{ return typeof(this.value1) != "undefined" && this.value1 != null; }-*/; 

    private native int getValue1() /*-{ return this.value1; }-*/; 

    private native boolean hasValue2() /*-{ return typeof(this.value2) != "undefined" && this.value2 != null; }-*/; 

    // no longs are allowed 
    private native double getValue2() /*-{ return this.value2; }-*/; 

    // TODO migrate to Java 8 
    public static final Function<Dto, DomainObject> dtoToDomainObject = new Function<Dto, DomainObject>() { 
     @Override 
     public DomainObject apply(Dto dto) { 
      return new DomainObject(
        dto.hasValue1() ? dto.getValue1() : null, 
        dto.hasValue2() ? (long) dto.getValue2() : null 
      ); 
     } 
    }; 

} 

. 하지만 이것은 적어도 다음과 같은 단점을 지닌 매우 거대한 상용구입니다 :

  • 위성 has -methods;
  • JavaScript 메서드를 사용하여 null 허용 여부를 확인하는 최소한 두 가지 검사 (한 가지 JavaScript 메서드로 추출 할 수 있지만 항상 쉬운 것은 아닙니다), 인공 지능 메서드 구현, 오타가 아닌;
  • 다른 접근 자에 속한 "외계인"인공위성 방법을 구성 할 수있게하는 typo-bulletproof가 아니라 nullable 메소드에 액세스하는 동안 3 진 연산자.
  • 어쩌면 내가 지금까지 보지 못한 다른 것일 수 있습니다.

나는 거대한 상용구없이 JSNI 메소드에 완전한 nullable 의미를 어떻게 사용하고 구현할 수 있습니까?

답변

1

많은 상용구를 줄이지는 않지만 (위에서 코드를 단순화 할 수는 있지만). 값이 null 경우

private native Integer getValue1() /*-{ 
    return this.value1 == null ? null : @java.lang.Integer::valueOf(I)(this.value1); 
}-*/; 

private native Long getValue2() /*-{ 
    return this.value2 == null ? null : @my.app.client.Dto::doubleToLong(D)(this.value2); 
}-*/; 

private static Long doubleToLong(double d) { 
    return Long.valueOf((long) d); 
} 

이 BTW, 첫 조각에 두 번에 걸친 코드가 잘못, 그것이 NPE를 슬로우 : 같은 코드가 보일 것이다. (또는 longValue())

+0

예, 그것은 NPE-안전하지 않은, 나는 나의 실험을하는 동안 원래의 첫 번째 버전을 잃었다 기억으로부터. BTW, 첫 네이티브 메소드 선언을 완성하기 위해';'를 놓쳤습니다. :) 나는 당신의 솔루션을 테스트 중이며 훌륭하게 작동합니다. 고맙습니다! –

+0

"BTW, 당신이 놓친 것';'최초의 네이티브 메소드 선언을 완료하는 것"Fixed, thanks. –

0

토마스가 말했듯이, JSNI에서 Java 유형으로 간단하게 상자를 만들 수있는 방법은 없습니다. 그 코드 스 니펫을 사용하여 필요할 때 자신의 조언과 수동으로 box/unbox 값을 따를 수도 있고, 준비가 된 boxing과 unboxing을 제공하는 lib에 의지 할 수 있습니다. 그러면 보일러 플레이트를 절약하고 JSNI 인터페이스를 사용할 수 있습니다 (때로는 짜증납니다) . 다음과 같이

터보 GWT 코어

, 당신이 당신의 클래스를 쓸 수 있습니다 : 첫 번째 조각은 단지 복원 된 있도록

private Integer getValue1() { 
    return Overlays.boxPropertyAsInteger(this, "value1"); 
} 

private Long getValue2() { 
    return Overlays.boxPropertyAsLong(this, "value2"); 
} 
+1

답해 주셔서 감사합니다. 귀하의 도서관은 유망 해 보입니다. 그래서 나중에 확인하겠습니다. :) –