Java Generics: 유형 삭제 및 와일드카드
13951 단어 corejava
Object
형식으로 변환됩니다. 이렇게 하면 제네릭 형식 매개 변수가 Object
메서드를 제외한 다른 메서드를 호출할 수 없습니다.Object
클래스에 있는 메소드가 아닌 다른 메소드를 호출하려면 어떻게 해야 합니까? 이 문서에서는 "와일드카드", "경계"및 "유형 삭제"가 무엇인지 설명합니다. 그리고 제네릭을 사용할 때 유연성을 높이기 위해 와일드카드를 사용하는 방법.유형 삭제
Wikipedia는 유형 삭제를 다음과 같이 정의합니다.
Type erasure is the load-time process by which explicit type annotations are removed from a program, before it is executed at run-time.
이 예제에서는 제네릭을 사용하므로 여러 유형에 사용할 수 있습니다.
class Container<T> {
private T contents;
public Container(T contents) {
this.contents = contents;
}
public T getContents() {
return contents;
}
public static void main(String[] args) {
Container<String> container = new Container<>("Hello!");
String contents = container.getContents();
System.out.println(contents);// Hello!
}
}
Container<String> container = new Container<>(“Hello!”);
를 입력할 때 유형T
을 String
로 대체한다고 생각할 수 있습니다. 그러나 컴파일 타임에 Java 컴파일러는 코드에서 일반 유형 매개변수T
를 제거하고 이를 Object
유형으로 대체합니다.class Container {
private Object contents;
public Container(Object contents) {
this.contents = contents;
}
public Object getContents() {
return contents;
}
public static void main(String[] args) {
Container container = new Container("Hello!");
String contents = (String) container.getContents();
System.out.println(contents);
}
}
String contents = container.getContents();
가 String contents = (String) container.getContents();
로 어떻게 변환되는지 주목하세요. 보시다시피 컴파일러는 getContents()
메서드를 호출할 때 캐스트를 삽입했습니다.와일드카드 제네릭 유형
?
로 표시되는 와일드카드는 "모든 유형"을 정의하려는 경우에 유용합니다.무제한 와일드 카드
제네릭 제약 조건 중 하나는 예를 들어
List<Integer>
인수를 List<Object>
매개변수에 전달할 수 없다는 것입니다. 그렇게 하면 컴파일 타임 오류가 발생합니다. Java가 사용자로부터 사용자를 보호하기 때문에 실제로는 좋은 일입니다!public static void processList(List<Object> list) {
for (Object o : list)
System.out.print(o);
}
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2);
processList(numbers); // compile-time error
}
이 예제는
List<Integer>
가 List<Object>
의 하위 유형이 아니기 때문에 작동하지 않습니다. 예상할 수 있듯이 List<Object>
매개변수의 processList
유형은 List<?>
로 대체되어야 합니다(읽기: 알 수 없는 유형 목록).이제 모든 종류의 List를
processList
메서드에 전달할 수 있습니다.public static void processList(List<?> list) {
for (Object o : list)
System.out.print(o);
}
public static void main(String[] args) {
List<Integer> list = List.of(1, 2);
processList(list);// 12
System.out.println();
List<String> strings = List.of("Hello", "World!");
processList(strings);// HelloWorld!
}
경계 와일드카드
제한된 와일드카드를 사용하면 컴파일러에서 형식에 대한 제한을 적용할 수 있습니다. 이 예에서는 제한된 와일드카드의 성능 및 안전성 이점을 보여줍니다.
public static void transformList(List<? extends CharSequence> list) {
List<Integer> charsCount = list.stream()
.map(CharSequence::length)
.collect(Collectors.toList());
System.out.println(charsCount);
}
public static void main(String[] args) {
List<String> stringList = List.of("Hello", "World", "!");
transformList(stringList);// [5, 5, 1]
List<StringBuilder> stringBuilders = List.of(new StringBuilder("Java"), new StringBuilder("Rocks"));
transformList(stringBuilders);// [4, 5]
}
transformList
가 하는 일은 List
를 취하여 List<Integer>
로 변환하여 각 요소의 길이를 표현하는 것입니다.transformList
의 매개변수는 List<? extends CharSequence>
이며, 이는 이 메서드가 CharSequence
, List<String>
와 같이 List<StringBuilder>
와 같이 CharSequence
의 하위 유형이 있는 모든 목록을 허용할 수 있음을 의미합니다. 이 메서드의 인수로 전달됩니다.마무리
이 게시물에서 Type Erasure의 개념을 명확히 하고 와일드카드와 경계를 소개했습니다. 그러나 제네릭에서 배울 것이 훨씬 더 많습니다. 궁금하고 더 알고 싶다면 이 종합Java Generics FAQ을 적극 추천한다.
이 게시물이 유용하다고 생각했다면 지금 무엇을 해야 하는지 알고 있습니다. 박수 버튼을 누르고 피드에 대한 더 많은 기사와 튜토리얼을 보려면 저를 팔로우하세요.
Reference
이 문제에 관하여(Java Generics: 유형 삭제 및 와일드카드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hamzajvm/java-generics-type-erasure-wildcards-3ml8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)