Java 제네릭스에서 ?와 오브젝트의 차이점은 무엇입니까?
자바 제네릭스를 올바르게 사용하기 위한 코드를 정리하는 데 도움이 되도록 이클립스를 사용하고 있습니다.대부분의 경우 유형을 추론하는 작업은 훌륭하지만 가능한 한 일반적인 유형이어야 하는 경우가 있습니다. 객체입니다.하지만 이클립스는 나에게 오브젝트의 종류와 '?'의 종류 중 하나를 선택할 수 있는 선택권을 주는 것 같다.
그렇다면 다음 두 가지 차이점은 무엇일까요?
HashMap<String, ?> hash1;
그리고.
HashMap<String, Object> hash2;
의 예HashMap<String, String>
일치하다Map<String, ?>
하지만 아니다Map<String, Object>
지도를 받는 방법을 쓰고 싶다고 합시다.String
s to anything :만약 당신이 쓴다면
public void foobar(Map<String, Object> ms) {
...
}
A를 공급할 수 없습니다.HashMap<String, String>
글을 쓰시면
public void foobar(Map<String, ?> ms) {
...
}
효과가 있다!
자바에서 가끔 오해되는 것은List<String>
의 서브타입이 아닙니다.List<Object>
(단,String[]
실제로는 의 아형이다Object[]
이것이 제네릭과 어레이가 잘 섞이지 않는 이유 중 하나입니다.(Java에서의 어레이는 공변이지만 제네릭은 그렇지 않고 불변입니다.)
샘플: 다음을 허용하는 방법을 쓰고 싶은 경우List
의InputStream
및 서브타입InputStream
, 당신은 글을 쓸 것이다.
public void foobar(List<? extends InputStream> ms) {
...
}
덧붙여서: Joshua Bloch의 Effective Java는 Java에서 그리 간단하지 않은 것들을 이해하고 싶을 때 훌륭한 리소스입니다.(위의 질문도 이 책에서 매우 잘 다루어져 있습니다.)
이 문제에 대해 생각할 수 있는 또 다른 방법은
HashMap<String, ?> hash1;
와 동등하다
HashMap<String, ? extends Object> hash1;
이 지식을 Java Generics and Collections 섹션 (2.4)의 "Get and Put 원칙"과 결합하십시오.
Get and Put 원칙: 구조에서 값을 가져올 때만 확장 와일드카드를 사용하고, 구조에만 값을 넣을 때는 슈퍼 와일드카드를 사용하며, get and put 모두 와일드카드를 사용하지 않습니다.
와일드카드가 좀 더 말이 될 수도 있을 것 같아요
그걸 기억하면 쉽게 이해할 수 있어Collection<Object>
유형 개체를 포함하는 일반 컬렉션입니다.Object
,그렇지만Collection<?>
모든 종류의 컬렉션 중 슈퍼 타입입니다.
공분산 위의 답변은 대부분의 경우를 포함하지만 한 가지를 놓칩니다.
"?"는 클래스 계층의 "개체"를 포함합니다.String은 객체의 일종이고 Object는 객체의 일종이라고 할 수 있습니다.모든 것이 Object와 일치하는 것은 아니지만 모든 것이 일치합니까?
int test1(List<?> l) {
return l.size();
}
int test2(List<Object> l) {
return l.size();
}
List<?> l1 = Lists.newArrayList();
List<Object> l2 = Lists.newArrayList();
test1(l1); // compiles because any list will work
test1(l2); // compiles because any list will work
test2(l1); // fails because a ? might not be an Object
test2(l2); // compiled because Object matches Object
어떤 것도 안전하게 넣을 수 없습니다.Map<String, ?>
값이 어떤 유형인지 모르기 때문입니다.
수 요.Map<String, Object>
은 이이 , , , , , , , , , , ,라고 알려져 있기 때문입니다Object
.
hash1
로 HashMap<String, ?>
「이러다」를 지정합니다.hash1
것이든 할 수 HashMap
가 「」라고 있다.String
모든 유형의 가치를 제공합니다.
HashMap<String, ?> map;
map = new HashMap<String, Integer>();
map = new HashMap<String, Object>();
map = new HashMap<String, String>();
위의 모든 것이 유효합니다.변수는 map
는 이러한 해시 맵을 저장할 수 있습니다.이 변수는 보유하고 있는 해시맵의 Value 타입에 관계없이 상관없습니다.
와일드카드를 사용한다고 해서 맵에 어떤 유형의 오브젝트도 넣을 수 없습니다.사실 위의 해시 맵에서는 위의 해시 맵을 사용하여 아무것도 맵에 넣을 수 없습니다.map
★★★★
map.put("A", new Integer(0));
map.put("B", new Object());
map.put("C", "Some String");
컴파일 시 오류가 는 HashMap의 을 알 수 입니다.Java "HashMap " 값 " "Java ' HashMap' 값입니다.map
을 사용하다 수 내에 어떤 에) 이 의 라고 할 수.Object
따라서 맵에서 얻는 것은 오브젝트 타입이 됩니다.
HashMap<String, Integer> myMap = new HashMap<>();// This variable is used to put things into the map.
myMap.put("ABC", 10);
HashMap<String, ?> map = myMap;
Object output = map.get("ABC");// Valid code; Object is the superclass of everything, (including whatever is stored our hash map).
System.out.println(output);
위의 코드 블록은 콘솔에 10을 인쇄합니다.
으로요.HashMap
) 즉, 「」, 「」, 「」, 「」의 ),HashMap
예를 들어 다음과 같습니다.
public static void printHashMapSize(Map<?, ?> anyMap) {
// This code doesn't care what type of HashMap is inside anyMap.
System.out.println(anyMap.size());
}
그 이외의 경우는, 필요한 타입을 클릭합니다.
public void printAThroughZ(Map<Character, ?> anyCharacterMap) {
for (int i = 'A'; i <= 'Z'; i++)
System.out.println(anyCharacterMap.get((char) i));
}
가 '키'라는을 알 .Character
그렇지 않으면 값을 얻기 위해 어떤 유형을 사용해야 하는지 알 수 없습니다.에는 「」가 .toString()
단, 맵은 값에 대해 임의의 유형의 개체를 가질 수 있습니다.을 사용하다
언급URL : https://stackoverflow.com/questions/678822/what-is-the-difference-between-and-object-in-java-generics
'programing' 카테고리의 다른 글
모바일에서의 여백/패딩 - Quasar Framework (VueJ) (0) | 2022.08.16 |
---|---|
Vue 컴포넌트에 동적으로 속성 추가 (0) | 2022.08.16 |
C은 무엇인가"정적"기능을 합니까? (0) | 2022.08.16 |
정적으로 연결된 라이브러리 간에 심볼 충돌을 처리하는 방법은 무엇입니까? (0) | 2022.08.16 |
여러 연결을 할 때 C에서 소켓타임아웃을 설정하려면 어떻게 해야 합니까? (0) | 2022.08.16 |