의 차이점은 무엇입니까 List
, List<?>
, List<T>
, List<E>
, 그리고 List<Object>
?
1. 목록
List
:는 원시 유형이므로 그렇지 않습니다 typesafe
. 캐스팅이 나쁜 경우에만 런타임 오류가 발생합니다. 캐스트가 나쁜 경우 컴파일 시간 오류가 필요합니다. 사용하지 않는 것이 좋습니다.
2. 목록 <?>
List<?>
무제한 와일드 카드입니다. 그러나 그것이 무엇인지 잘 모르겠습니다. List<?>
문제없이 인쇄 할 수 있습니다 .
public static void test(List<?> list){
System.out.println(list); // Works
}
에 항목을 추가 할 수없는 이유는 무엇 List<?>
입니까?
public static void test(List<?> list){
list.add(new Long(2)); // Error
list.add("2"); // Error
System.out.println(list);
}
3.리스트 <T>
public static void test(List<T> list){ // T cannot be resolved
System.out.println(list);
}
이 구문을 이해하지 못합니다. 나는 이와 같은 것을 보았고 효과가있다.
public <T> T[] toArray(T[] a){
return a;
}
때때로, 나는 참조 <T>
하거나 <E>
, 또는 <U>
, <T,E>
. 그들은 모두 같습니까 아니면 다른 것을 나타 냅니까?
4.리스트 <개체>
이 오류는 “이 방법 test(List<Object>)
은 인수에 적용 할 수 없습니다 List<String>
“입니다.
public static void test(List<Object> list){
System.out.println(list);
}
나는 다음이를하려고하면 나는 “에서 캐스팅 할 수 없습니다 얻었다 List<String>
에 List<Object>
“
test((List<Object>) names);
혼란 스러워요. String
의 서브 클래스입니다 Object
왜하지, List<String>
의 서브 클래스 List<Object>
?
답변
1) 수정
2) 항목 유형에 신경 쓰지 않는 “읽기 전용”목록으로 생각할 수 있습니다. 예를 들어 목록의 길이를 반환하는 메서드에서 사용할 수 있습니다.
3) T, E 및 U는 동일하지만 사람들은 유형에 T, 요소에 E, 값에 V, 키에 K를 사용하는 경향이 있습니다. 컴파일하는 메소드는 특정 유형의 배열을 가져 와서 동일한 유형의 배열을 반환한다고 말합니다.
4) 오렌지와 사과는 섞을 수 없습니다. 문자열 목록을 개체 목록이 필요한 메서드에 전달할 수 있다면 문자열 목록에 개체를 추가 할 수 있습니다. (그리고 모든 객체가 문자열은 아닙니다)
답변
마지막 부분 : String은 Object의 하위 집합이지만 List <String>은 List <Object>에서 상속되지 않습니다.
답변
이 표기법 List<?>
은 “뭔가의 목록 (그러나 나는 무엇을 말하지 않습니까)”을 의미합니다. 코드 test
는 목록에있는 모든 종류의 객체에서 작동하므로 공식적인 메소드 매개 변수로 작동합니다.
포인트 3과 같이 타입 파라미터를 사용하려면 타입 파라미터를 선언해야합니다. 이를위한 Java 구문 <T>
은 함수 앞에 놓 입니다. 이것은 메소드 본문에서 이름을 사용하기 전에 공식 매개 변수 이름을 메소드에 선언하는 것과 정확히 유사합니다.
를 List<Object>
받아들이지 않는 것에 관해서 는 List<String>
, a String
가 아니기 때문에 의미 가 있습니다 Object
. 의 하위 클래스입니다 Object
. 수정은 선언하는 것 public static void test(List<? extends Object> set) ...
입니다. 그러나 extends Object
모든 클래스는 직간접 적으로 확장되기 때문에 중복됩니다 Object
.
답변
당신이 캐스팅 할 수없는 이유 List<String>
에는 List<Object>
당신이의 제약을 위반하는 것을 허용 할 것입니다 List<String>
.
다음 시나리오를 생각해보십시오.가있는 경우 List<String>
유형의 객체 만 포함해야합니다 String
. ( final
클래스 인)
이를에 캐스트 할 수 있으면 해당 목록 List<Object>
에 추가 Object
하여의 원래 계약을 위반할 수 List<String>
있습니다.
따라서 일반적으로 클래스 C
클래스의 상속은 P
, 당신이 말할 수 없다 GenericType<C>
또한 상속 GenericType<P>
.
NB 나는 이미 이전 답변에서 이것에 대해 언급했지만 그것을 확장하고 싶었습니다.
답변
자바 퍼즐을 읽는 것이 좋습니다. 선언의 상속, 제네릭, 추상화 및 와일드 카드에 대해 잘 설명합니다.
http://www.javapuzzlers.com/
답변
자바 역사의 맥락에서 그들에 대해 이야기하자;
List
:
목록은 모든 객체를 포함 할 수 있음을 의미합니다. 리스트는 Java 5.0 이전의 릴리스에있었습니다. Java 5.0은 이전 버전과의 호환성을 위해 List를 도입했습니다.
List list=new ArrayList();
list.add(anyObject);
List<?>
:
?
알 수없는 객체를 의미합니다. 와일드 카드 ?
소개는 Generic Type으로 작성된 문제를 해결하기위한 것입니다. 와일드 카드 참조 ; 그러나 이것은 또 다른 문제를 일으킨다 :
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
List< T> List< E>
프로젝트 Lib에 T 또는 E 유형이 없음을 전제로 일반 선언을 의미합니다.
List< Object>
일반 매개 변수화를 의미합니다.
답변
세 번째 관점에서, “T”는 선언되지 않았기 때문에 해결할 수 없습니다. 일반적으로 일반 클래스를 선언 할 때 “T”를 바인딩 된 유형 매개 변수 의 이름으로 사용할 수 있습니다. 오라클의 자습서를 포함한 많은 온라인 예제 에서는 “T”를 예를 들어 type 매개 변수의 이름은 다음과 같은 클래스를 선언합니다.
public class FooHandler<T>
{
public void operateOnFoo(T foo) { /*some foo handling code here*/}
}
당신이 것을 말하는 FooHandler's
operateOnFoo
방법을 염두에두고, 클래스 선언 자체에 선언 된 유형 “T”의 변수를 기대하고, 나중에 같은 다른 방법을 추가 할 수 있습니다
public void operateOnFoos(List<T> foos)
모든 경우에 T, E 또는 U에 유형 매개 변수의 모든 식별자가 있으며 구문을 사용하는 둘 이상의 유형 매개 변수를 가질 수도 있습니다.
public class MyClass<Atype,AnotherType> {}
네 번째 ponint에서 Sting은 Object의 하위 유형이지만 generics 클래스에는 그러한 관계 List<String>
가 없으며 하위 유형이 아니며 List<Object>
컴파일러 관점에서 두 가지 유형이 있습니다. 이 블로그 항목 에서 가장 잘 설명됩니다.