programing

메서드의 삭제가 형식의 다른 메서드와 동일합니다.

prostudy 2022. 8. 1. 20:50
반응형

메서드의 삭제가 형식의 다른 메서드와 동일합니다.

다음 두 가지 방법을 같은 클래스에 사용하는 것이 합법적이지 않은 이유는 무엇입니까?

class Test{
   void add(Set<Integer> ii){}
   void add(Set<String> ss){}
}

이해하다compilation error

메서드 add(Set)의 삭제 add(Set)는 테스트 유형의 다른 메서드와 동일합니다.

작업도 할 수 있는데 왜 javac이 이걸 싫어하는지 궁금해서요.

많은 경우 이 두 가지 방법의 논리는 매우 유사하며 하나의 방법으로 대체될 수 있습니다.

public void add(Set<?> set){}

방법은 다르지만 항상 그렇지는 않습니다.

두 개 갖고 싶으면 더 짜증나요.constructors그런 주장들을 받아들인다. 왜냐하면 그렇게 되면 그 중 하나의 이름을 바꿀 수 없기 때문이다.constructors.

이 규칙은 여전히 원시 유형을 사용하는 레거시 코드의 충돌을 방지하기 위한 것입니다.

이것은 JLS에서 가져온, 이것이 허가되지 않은 이유에 대한 그림입니다.제네릭스가 Java에 도입되기 전에 다음과 같은 코드를 작성했다고 가정해 보겠습니다.

class CollectionConverter {
  List toList(Collection c) {...}
}

내 수업을 이렇게 연장하는군

class Overrider extends CollectionConverter{
  List toList(Collection c) {...}
}

제네릭스의 도입 후, 저는 라이브러리를 갱신하기로 결정했습니다.

class CollectionConverter {
  <T> List<T> toList(Collection<T> c) {...}
}

업데이트를 할 준비가 되지 않았으므로 다음 정보를 남깁니다.Overrider수업시간만.올바르게 덮어쓰려면toList()방법, 언어 설계자는 원시 유형이 모든 생성 유형에 "일관성" 있다고 결정했다.즉, 메서드의 시그니처는 더 이상 정식으로 슈퍼클래스의 시그니처와 동일하지 않지만 메서드는 여전히 오버라이드됩니다.

이제 시간이 지나고 클래스를 업데이트할 준비가 되었다고 판단합니다.하지만 넌 좀 망쳤지 그리고 기존의 편집 대신, 날것으로toList()method는 다음과 같은 새로운 방법을 추가합니다.

class Overrider extends CollectionConverter {
  @Override
  List toList(Collection c) {...}
  @Override
  <T> List<T> toList(Collection<T> c) {...}
}

raw 타입의 오버라이드 등가성으로 인해 두 메서드는 모두 유효한 형식으로 재지정됩니다.toList(Collection<T>)방법.그러나 물론 컴파일러는 하나의 방법을 해결해야 합니다.이 애매함을 없애기 위해 클래스에는 덮어쓰기 등가 메서드를 여러 개 사용할 수 없습니다.즉, 삭제 후 파라미터 타입이 같은 메서드를 여러 개 사용할 수 없습니다.

중요한 점은 이 규칙이 원시 유형을 사용하여 이전 코드와의 호환성을 유지하도록 설계된 언어 규칙이라는 것입니다.이는 타입 파라미터 삭제에 필요한 제한이 아닙니다.메서드 해결은 컴파일 시에 이루어지기 때문에 메서드 식별자에 범용 타입을 추가하는 것으로 충분합니다.

Java ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」괄호 안의 ('' ')<Integer> ★★★★★★★★★★★★★★★★★」<String>시그니처가 ('2')가add(Set)에러에 표시됩니다).런타임에서는 각 케이스에 어떤 것을 사용해야 하는지 알 수 없기 때문에 허용되지 않습니다.

Java가 제네릭으로 재인증되면 이 작업을 수행할 수 있지만, 지금은 그럴 가능성이 거의 없습니다.

이는 Java Generic이 유형 삭제와 함께 구현되기 때문입니다.

메서드는 컴파일 시 다음과 같이 변환됩니다.

메서드 해결은 컴파일 시 이루어지며 유형 매개 변수를 고려하지 않습니다.(Erickson의 답변 참조)

void add(Set ii);
void add(Set ss);

두 메서드 모두 타입 파라미터가 없는 시그니처가 동일하기 때문에 에러가 발생합니다.

는 제는 the the the the the the the the theSet<Integer> ★★★★★★★★★★★★★★★★★」Set<String> Set 정수)을하는 것은일 뿐입니다.집합의 유형(이 경우 문자열 또는 정수)을 선택하는 것은 컴파일러가 사용하는 구문설탕일 뿐입니다.이 JVM을 수 .Set<String> ★★★★★★★★★★★★★★★★★」Set<Integer>.

를 들어 '하다'와 같은 하지 않는 을 정의합니다.void add(Set ii){}

원하는 대로 메서드를 호출하면서 유형을 언급할 수 있습니다.어떤 세트에서도 사용할 수 있습니다.

컴파일러가 Java 바이트 코드에서 Set(Integer)를 Set(Object)로 변환할 수 있습니다.이 경우 Set(Integer)는 구문체크를 위해 컴파일 단계에서만 사용됩니다.

걸 보게 됐어요.Continuable<T> callAsync(Callable<T> code) {....} ★★★★★★★★★★★★★★★★★」Continuable<Continuable<T>> callAsync(Callable<Continuable<T>> veryAsyncCode) {...}.Continuable<> callAsync(Callable<> veryAsyncCode) {...}

형식 삭제는 문자 그대로 제네릭에서 형식 인수 정보를 지우는 것을 의미합니다.이것은 매우 성가신 일이지만, 이것은 당분간 자바에 있을 제한 사항입니다.컨스트럭터 케이스의 경우, 예를 들어 컨스트럭터에서 다른 파라미터로 특화된2개의 새로운 서브클래스가 있습니다.또는 초기화 방법을 대신 사용합니다.(가상 생성자?) 이름이 다른...

유사한 조작 방법의 경우 이름을 변경하는 것이 도움이 됩니다.

class Test{
   void addIntegers(Set<Integer> ii){}
   void addStrings(Set<String> ss){}
}

좀 더 쉬운 이름, 예를 들어 케이스에 대한 자기 과 같은 .addNames ★★★★★★★★★★★★★★★★★」addIndexes그런 것 같아요.

언급URL : https://stackoverflow.com/questions/1998544/method-has-the-same-erasure-as-another-method-in-type

반응형