2014-11-24 1 views
11

에 정수 변환 :자바 8 - 나는 내 프로젝트에서 다음과 같은 추상적 인 일반 데이터 홀더 (간체) 한 긴 컴파일 문제

: Objects의 목록을 포함하는 InputCollection과 함께

public abstract static class Value<E> { 

    E value; 

    public void setValue(E value) { 
     this.value = value; 
    } 

    public E getValue() { 
     return this.value; 
    } 

    public String toString() { 
     return "[" + value + "]"; 
    } 
} 

public static class InputCollection { 

    private ArrayList<Object> values; 

    public InputCollection() { 
     this.values = new ArrayList<>(); 
    } 

    public void addValue(Value<?> value) { 
     System.out.println("addding " + value + " to collection"); 
     this.values.add(value); 
    } 

    public <D> D getValue(Value<D> value, D defaultValue) { 
     int index = this.values.indexOf(value); 
     if (index == -1) 
      return defaultValue; 

     Object val = this.values.get(index); 
     if (val == null) { 
      return defaultValue; 
     } 

     return ((Value<D>)val).getValue(); 
    } 
} 

이 뒤에 아이디어과 같이, 소위 '상태'에서이 abstractValue<E>를 구현 final 변수 세트를 정의 할 수 있습니다 :

public static final class Input<E> extends Value<E> { 
    public static final Input<String> STRING_ONE = new Input<String>(); 
    public static final Input<Integer> INTEGER_ONE = new Input<Integer>(); 
} 

그런 다음 이러한 변수를 InputCollection의 인스턴스에 추가합니다.이 인스턴스는 많은 '상태'또는 '프로세스'에서 차례로 공유됩니다. 그런 다음 Input<E>의 값을 다른 상태로 변경 한 다음 원래 상태로 필요할 때 검색 할 수 있습니다. 일종의 공유 메모리 모델.

구현

추가 자바 7에 근무에도 불구하고,이 개념은 세 (참,이 유산이다)을 위해 잘 작동하고있다, 그러나 우리는 최근 자바 8 이상 움직이기 시작하고, 이것은 컴파일 오류를 생성 위의 코드 샘플에 다음 main : 이클립스 컴파일러 준수 레벨이 1.7로 설정되어있는 경우

public static void main (String [] args) { 

    InputCollection collection = new InputCollection(); 
    //Add input to collection 
    collection.addValue(Input.STRING_ONE); 
    collection.addValue(Input.INTEGER_ONE); 

    //At some later stage the values are set 
    Input.INTEGER_ONE.setValue(1); 
    Input.STRING_ONE.setValue("one"); 

    //Original values are then accessed later 
    long longValue = collection.getValue(Input.INTEGER_ONE, -1); 

    if (longValue == -1) { 
     System.out.println("Error: input not set"); 
    } else { 
     System.out.println("Input is: " + longValue); 
    } 
} 

, 아니 컴파일 문제가 없으며, 출력이 제대로 될 것입니다 :

addding [null] to collection 
addding [null] to collection 
Input is: 1 

있지만 라인

long longValue = collection.getValue(Input.INTEGER_ONE, -1); 

에 1.8 컴파일 오류 Type mismatch: cannot convert from Integer to long로 설정하지만이 일을 값에 액세스하는 경우 경우 :

long longVal = Input.INTEGER_ONE.getValue(); 

가 혼란 어떤 컴파일 문제가 없습니다.

이것은 캐스트로 해결할 수 있지만 프로젝트 전체에서 사용되며 모든 발생을 변경하려면 상당히 엄격한 필수 테스트가 필요합니다.

캐스트가 필요한 Java 8의 변경된 사항은 무엇입니까? 컴파일은 어떻게 든 더 엄격 해졌습니까? 왜 값이 콜렉션을 통하지 않고 직접 액세스되는 경우 컴파일러는 신음을하지 않습니까?

나는 How do I convert from int to Long in Java?Converting Integer to Long를 읽을 수 있지만 정말 내 질문에 만족스러운 답변을하지 않았다.

+1

이것을'javac'로 컴파일 해 볼 수 있습니까? 나는 또한이 문제점을 가지고 있고 나는 그것이 식량 결함이라고 믿는다. 코드에 캐스트를 추가하면 "불필요한 캐스트"경고가 표시됩니다. :) –

+0

내 컴퓨터에서 복제 할 수 없습니다. 그것은 Java8에서 내 문제없이 완벽하게 작동합니다. – Jatin

+2

사실 이것은 Eclipse 내부 컴파일러의 버그입니다. 주 : Eclipse는 설치된 JDK에서'javac' 명령을 사용하지 않지만 내부 컴파일러를 사용합니다. 이 컴파일러는 오류를보고합니다. JDK 도구로 컴파일하면 잘 작동합니다. – Seelenvirtuose

답변

7

JLS for Java 8에 따르면 이런 일이 발생하지 않아야

5.1.2. 기본 변환 프리미티브 타입에

19 개 특정 확장 변환하는 확개 프리미티브 전환이라고 :

[..]

  • 긴 플로트에 INT 또는 이중

[...]

5.1.8. 개봉기 변환

는 [...] 정수형 가입일

  • 타이핑하는 INT
  • 무엇 일어나야하는 Integer에서 int에 개봉기하고 long로 확장 변환이

. 이것은 실제로 Oracle JDK (1.8.0.25)에서 예상대로 발생합니다.

당신이 JDK에 컴파일러 버그를 발견했다고 생각합니다. 아마도 업데이트 된 버전을 시도하거나 관리자에게 버그를 신고해야합니다.

+1

당신 말이 맞습니다. JDK에서'javac'를 사용하면 잘 동작합니다. Eclipse 컴파일러의 버그 인 것 같습니다. – Seelenvirtuose

+2

Eclipse 화성 4.5.0에서 수정 된 것 같습니다 – Ian2thedv

6

공지 이클립스 버그 :

https://bugs.eclipse.org/bugs/show_bug.cgi?id=440019 이클립스 4.5 M3에 고정.

+0

STS 3.6에서 수정 사항을 얻을 수있는 방법이 있었으면 좋겠는데 .. 거기 있습니까? – jayP

+0

나는 그것을 모르고있다. 간단히 새 버전을 다운로드 했으므로 괜찮습니다. 하지만 네, 업그레이드를 원하지 않는 설치를 상상할 수도 있습니다. 어딘가에있는 사람들에게 연락을 시도하십시오. –