IT이야기

일반 반환 유형 상한 - 인터페이스 대 클래스 - 놀랍도록 유효한 코드

cyworld 2022. 5. 27. 21:22
반응형

일반 반환 유형 상한 - 인터페이스 대 클래스 - 놀랍도록 유효한 코드

이것은 서드파티 라이브러리 API의 실제 예이지만 단순화되어 있습니다.

Oracle JDK 8u72를 사용하여 컴파일

다음 두 가지 방법을 고려합니다.

<X extends CharSequence> X getCharSequence() {
    return (X) "hello";
}

<X extends String> X getString() {
    return (X) "hello";
}

두 사람 모두 "확인되지 않은 출연자" 경고를 보고한다. 왜 그런지 알겠다.나를 당혹스럽게 하는 것은 왜 전화를 할 수 있는가 하는 것이다.

Integer x = getCharSequence();

파일일 할???는 이 .Integer does does does does 。CharSequence의 콜

Integer y = getString();

(예상대로) 에러를 표시합니다.

incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String

누가 왜 이 행동이 유효한 것으로 간주되는지 설명해 줄 수 있나요?어떻게 도움이 될까요?

클라이언트는 이 콜이 안전하지 않은지 모르고 클라이언트의 코드가 경고 없이 컴파일됩니다.컴파일이 그것에 대해 경고하지 않거나 오류를 발생시키지 않는 이유는 무엇입니까?

또, 이 예와 어떻게 다른가.

<X extends CharSequence> void doCharSequence(List<X> l) {
}

List<CharSequence> chsL = new ArrayList<>();
doCharSequence(chsL); // compiles

List<Integer> intL = new ArrayList<>();
doCharSequence(intL); // error

하려고 하다List<Integer>에러가 표시됩니다.

method doCharSequence in class generic.GenericTest cannot be applied to given types;
  required: java.util.List<X>
  found: java.util.List<java.lang.Integer>
  reason: inference variable X has incompatible bounds
    equality constraints: java.lang.Integer
    upper bounds: java.lang.CharSequence

되고 있는 는, 왜 「」 「」 「」 「」 「」가 되는 것입니까.Integer x = getCharSequence(); 안그래?

CharSequence는 입니다.interface따라서,SomeClass does does does does 。CharSequence 수 것 .

class SubClass extends SomeClass implements CharSequence

그러므로 당신은 글을 쓸 수 있다.

SomeClass c = getCharSequence();

는, 「유추형」이 「유추형」이기 때문입니다.X입니다.SomeClass & CharSequence.

는 좀 요.IntegerInteger이지만, final이 규칙들에서는 아무런 역할도 하지 않습니다.를 들면 '어리다'라고 쓰면 요.

<T extends Integer & CharSequence>

반,는String 아니다interface할 수 SomeClassStringjava는 클래스에 대해 멀티 테넌스를 지원하지 않기 때문입니다.

List예를 들어, 제네릭이 공변량도 아니고 반변량도 아니라는 점을 기억해야 합니다., ,, 약의 X는 의 입니다.Y,List<X>서브타입도 슈퍼타입도 아니다.List<Y> .부터Integer does does does does 。CharSequence , 는 사용할 수 .List<Integer> 안에서doCharSequence★★★★★★ 。

단, 컴파일 할 수 있습니다.

<T extends Integer & CharSequence> void foo(List<T> list) {
    doCharSequence(list);
}  

반환하는 메서드가 있는 경우List<T>음음음같 뭇매하다

static <T extends CharSequence> List<T> foo() 

할수있습니다

List<? extends Integer> list = foo();

Integer & CharSequence은 '아형'의 입니다.Integer.

은 여러 할 때 암묵적으로 " " " " " " " " " ).<T extends SomeClass & CharSequence>를 참조해 주세요.

상세한 것에 대하여는, JLS 의 각 부분으로부터 타입 바운드의 구조를 설명합니다.예를 들어, 복수의 인터페이스를 포함할 수 있습니다.

<T extends String & CharSequence & List & Comparator>

단, 첫 번째 바인드만 비인터페이스일 수 있습니다.

되기 전에 컴파일러에 .XInteger & CharSequence이런 타입은 느낌이 이상해요 왜냐하면Integer최종적인 것이지만 자바에서는 완전히 유효한 타입입니다.그 후, 로 보내집니다.Integer그건 완벽하게 괜찮아요.

에는 1개의 가능한 값이 있습니다.Integer & CharSequence입력:null. 다음과 같은 구현:

<X extends CharSequence> X getCharSequence() {
    return null;
}

다음 할당이 작동합니다.

Integer x = getCharSequence();

이러한 가능한 가치 때문에, 비록 그것이 명백히 쓸모없다고 해도, 그 과제가 틀릴 이유는 없다.경고는 도움이 될 것이다.

진짜 문제는 API이지 콜사이트가 아닙니다

사실, 저는 최근에 이 API 디자인 안티 패턴에 대해 블로그에 글을 올렸습니다.임의의 유형을 반환하는 일반적인 방법을 설계하지 마십시오.추정된 유형이 전달되는 것을 (거의) 보장할 수 없기 때문입니다.예외는 다음과 같은 방법입니다.Collections.emptyList()리스트의 공허함(및 범용 타입 삭제)이, 에 대한 추론이 있는 경우.<T>동작합니다.

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

언급URL : https://stackoverflow.com/questions/36402646/generic-return-type-upper-bound-interface-vs-class-surprisingly-valid-code

반응형