programing

Java 제네릭스에서 ?와 오브젝트의 차이점은 무엇입니까?

nicescript 2022. 8. 16. 22:09
반응형

Java 제네릭스에서 ?와 오브젝트의 차이점은 무엇입니까?

자바 제네릭스를 올바르게 사용하기 위한 코드를 정리하는 데 도움이 되도록 이클립스를 사용하고 있습니다.대부분의 경우 유형을 추론하는 작업은 훌륭하지만 가능한 한 일반적인 유형이어야 하는 경우가 있습니다. 객체입니다.하지만 이클립스는 나에게 오브젝트의 종류와 '?'의 종류 중 하나를 선택할 수 있는 선택권을 주는 것 같다.

그렇다면 다음 두 가지 차이점은 무엇일까요?

HashMap<String, ?> hash1;

그리고.

HashMap<String, Object> hash2;

의 예HashMap<String, String>일치하다Map<String, ?>하지만 아니다Map<String, Object>지도를 받는 방법을 쓰고 싶다고 합시다.Strings 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에서의 어레이는 공변이지만 제네릭은 그렇지 않고 불변입니다.)

샘플: 다음을 허용하는 방법을 쓰고 싶은 경우ListInputStream및 서브타입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.

hash1HashMap<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

반응형