Varargs Java 모호한 호출
Java의 varargs 메서드 에 대해 약간 혼란 스럽습니다 .
public static int sum(int ...a) {
return 0;
}
public static double sum(double ...a) {
return 0.0;
}
sum()
인수를 전달하지 않고 호출하려고하면 int
메서드 버전이 호출되었습니다. 이유를 이해하지 못합니다. 일반적으로 컴파일러는 오류를 발생시켜야합니다.
반대로 다음 코드는 sum
인수없이 호출하려고하면 컴파일러 오류를 생성합니다 .
public static int sum(int ...a) {
return 0;
}
public static boolean sum(boolean ...a) {
return true;
}
여기에 적용되는 일반적인 규칙은 다음과 같습니다. 하나의 메소드 서명이 다른 것보다 엄격하게 더 구체적 이면 Java는 오류없이이를 선택합니다.
직관적으로 메소드 서명은 완전히 삭제할 수 있다면 더 구체적이고 다른 하나는 기존의 각 호출에 적용 할 수있는 덜 구체적인 것입니다.
서명 sum(int... args)
과 사이의 선택이 제공되면 해당 메서드의 모든 호출이 확장 변환을 적용하여 전달 될 수 있기 때문에 sum(double... args)
서명 sum(int... args)
이 더 구체적 sum(double... args)
입니다. sum(boolean... args)
비슷하게 변환 할 수없는 메서드도 마찬가지 입니다.
Java 언어 사양, SE 8 버전 :
15.12. 메서드 호출 식
15.12.2.5. 가장 구체적인 방법 선택
Java 프로그래밍 언어는 가장 구체적인 방법이 선택 되는 규칙을 사용합니다 .
...
다음 중 하나에 해당하는 경우 인수 표현식 e1, ..., ek를 사용한 호출에 대해 적용 가능한 방법 m1이 다른 적용 가능한 방법 m2보다 더 구체적입니다.
...
- m2는 제네릭이 아니며 m1 및 m2는 엄격 또는 느슨한 호출에 의해 적용 가능하며 m1에 형식 매개 변수 유형 S1, ..., Sn 및 m2가있는 경우 형식 매개 변수 유형 T1, ..., Tn, 유형 Si가 더 많습니다. 모든 i (1 ≤ i ≤ n, n = k)에 대한 인수 ei에 대해 Ti보다 구체적 입니다.
...
유형 S는 S <: T (§4.10) 인 경우 모든 표현식에서 유형 T보다 더 구체적입니다.
4.10. 서브 타이핑
4.10.1. 기본 유형 간의 하위 유형 지정
double> 1 float
플로트> 1 길이
long> 1 int
이 답변 에서 언급했듯이 사용할 오버로드 된 방법을 선택할 때 따르는 규칙이 있습니다.
인용하려면 :
- 기본 확장은 가능한 가장 작은 메서드 인수를 사용합니다.
- 래퍼 유형은 다른 래퍼 유형으로 확장 할 수 없습니다.
- int에서 Integer로 Box하고 Object로 넓힐 수 있지만 Long은 아닙니다.
- Widening Beats Boxing, Boxing Beats Var-args.
- Box 및 Widen 수 있습니다 (int는 Integer를 통해 Object가 될 수 있음).
- 넓히고 나서 Box 할 수 없습니다 (int는 Long이 될 수 없습니다)
- 당신과 함께, VAR-인수를 결합 할 수 없습니다 모두 확대 와 권투.
(규칙 1을 다음과 같이 재정의합시다. "기본 확대는 가능한 한 가장 구체적인 메서드 인수를 사용합니다.")
따라서 이러한 규칙을 염두에두고 여기서 무슨 일이 일어나고 있는지 알 수 있습니다.
첫 번째 규칙에 따르면 기본 확장은 가능한 한 가장 구체적인 메서드 인수를 사용합니다. 이 때문에 int
비 진수 (예 :로 표현이다 1
)과는 double
32 바이트 더보다 정밀도로 진수로 표현된다 float
(예를 들면 1.0
), 우리는 말할 수 int
S는 "미만"또는 "보다 작은"이다 double
들, 그 논리에 의해, int
들에 "승진"할 수 double
의과 double
들에 "강등"수 int
의.
Put simply, a primitive that can be widened to another primitive (e.g. int
-> float
-> double
) is more specific than another. For example, an int
is more specific than a double
because 1
can be promoted to 1.0
.
When you passed in no arguments to these overloaded vararg methods of the same name, since the return is effectively the same (0 and 0.0 respectively), the compiler would choose to use the method that takes in a vararg of type int
since it is more specific.
So, then, when you introduced these same methods that take in int
s and boolean
s (types that cannot be widened to each other) respectively, the compiler now cannot choose a method to use since int
s cannot be "promoted" or "demoted" like int
s, float
s and double
s. Therefore, it will throw a compile error.
I hope this helps you to understand what's happening.
참고URL : https://stackoverflow.com/questions/31627236/varargs-java-ambiguous-call
'Programing' 카테고리의 다른 글
HTTP Put은 어떻게합니까? (0) | 2020.11.09 |
---|---|
Chrome / Chromium 및 Safari에서 끌어서 놓기 파일 업로드? (0) | 2020.11.09 |
포인터에 메모리 할당 여부 확인 (0) | 2020.11.09 |
Entity Framework-Include ()없이 자식 엔터티를 자동으로 즉시로드하는 방법이 있습니까? (0) | 2020.11.09 |
Just-In-Time 컴파일과 Ahead-of-Time 컴파일의 장점은 무엇입니까? (0) | 2020.11.09 |