2017-09-04 18 views
7

다음 두 가지 메소드를 고려하십시오. 첫 번째 것은 받아 들여지고 두 번째 것은 모호한 것으로 거부됩니다. 유일한 차이점은 int와 Integer를 사용하는 것입니다.Object 및 기본 유형이있는 애매한 varargs 메소드

특히 두 번째 것을 거부해야합니까? 그것은 권투 (첫 번째 세트로 이어질 것입니다) 후 그것을 받아들이는 것이 문제가 있음을 암시합니다. 나는 여기서 무엇을 놓칠까요?

필자의 견해로는 Java 컴파일러가 너무 제한적입니다.

세트 1 :

public void test(Object... values) {} 

public void test(Integer x, Object... values) {} // difference here 

public void b() { 
    test(1, "y"); // accepted 
} 

세트 2 :

error: reference to test is ambiguous 
    test(1, "y"); // marked as ambiguous 
    ^
    both method test(Object...) in T and method test(int,Object...) in T match 

자바 1.8, 이클립스 산소

+0

Set 1과 Set 2의 메토는 같은 등급입니까? –

+1

@RafaelVieiraCoelho 물론 아닙니다. – Kayaman

+0

동일한 클래스. 클래스를 편집하여 둘 사이를 변경합니다. –

답변

1

이 차이는 다음과 같습니다

public void test(Object... values) {} 

public void test(int x, Object... values) {} // difference here 

public void b() { 
    test(1, "y"); // marked as ambiguous 
} 

세트 2 컴파일러 오류가 발생합니다 첫 번째 경우, t 그는 1 인수를 Integer로 묶어야하고 가장 적합한 방법을 선택해야합니다. 그 버전은 (Integer, Object...)입니다.

두 번째 경우에는 복싱인지 아닌지의 두 가지 옵션이 있습니다. 이것이 모호한 이유입니다.

나는 이것이 반 직관적이라는 데 동의합니다.

+0

나는 동의합니다, 컴파일러가 올바르게 스펙을 구현합니다. 필자의 요점은 Java 컴파일러가 컴파일 타임에이 제한을 쉽게 풀 수 있다는 점입니다. 복잡한 분석이 필요하지 않습니다. 사양이 너무 제한적입니다. –

5

컴파일러가 수행하는 작업은 호출에 대해 여러 메서드가 적용될 수있는 경우 가장 구체적인 메서드를 선택하기 위해 JLS 15.12.2.5에 설정된 규칙을 구현하는 것입니다. 귀하의 질문의 예에서, 차이는 스펙이 선으로 덮여있다 :

A type S is more specific than a type T for any expression if S <: T (§4.10).

S <: TST의 하위 유형을 의미합니다. 예 # 1에서

:

두 가지 적용 방법
  • 유형 IntegerObject의 하위 유형이는, 그래서 더 특정
    • .
    • 따라서 두 번째 방법은 첫 번째 방법보다 더 구체적입니다.
    • 따라서 두 번째 방법이 선택됩니다. 예 # 2에서

    :

    두 가지 적용 방법
  • 유형 intObject 또는 그 반대의 서브 타입이되지 않는, 그래서 어느 유형이 다른 것보다 더 구체적이다
    • .
    • 따라서 두 방법 모두 다른 방법보다 더 구체적이지 않습니다.
    • 따라서 호출이 모호합니다.
  • 0

    이 문제를 종료하려면 실제 질문에 대한 대답을 이해함에 따라 요약 해주십시오. 사양에 따라 동작이 정확합니다. 원시 타입이 비 프리미티브 (non-primitive) 대응 물로서 커버되도록 명세는 완화 될 수있다. 아직 완료되지 않은 한 가지 이유는 빠르고 정확한 구문 분석기를 지정하고 구현하는 복잡성 때문입니다.