>  기사  >  Java  >  Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?

Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?

王林
王林앞으로
2023-05-11 18:10:061287검색

첫 번째 두 가지 코드:

public static <T> void show1(List<T> list){
 for (Object object : list) {
        System.out.println(object.toString());
    }
}

public static void show2(List<?> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

show1 메소드에서 T를 사용하는 것을 볼 수 있습니다. 이것이 제네릭을 작성하는 일반적인 방법이라는 것을 누구나 알고 있으므로 여기서 T는 특정 유형의 특정 객체를 나타냅니다. 동일한 유형의 데이터를 저장할 수 있습니다. 다른 유형의 데이터가 삽입되면 오류가 보고됩니다.

그럼 show2 메소드에서는 무엇을 사용하나요? , void? 앞에 <t></t>가 없는 것을 볼 수 있습니다. 자리 표시자로 표현될 수 있으며 목록 모음에 얼마나 많은 유형의 데이터가 저장될지 알 수 없으므로 목록에 N개의 데이터 유형을 저장할 수도 있음을 보여줍니다. <t></t>,?可以表示成占位符,它自己也不知道list集合中会存放多少种类型的数据,所以这样就表明我们的list中存放N种数据类型也是可以的。

我们通过一段测试代码来直观的感受一下二者的区别吧:

public static void test(){
   List<Student> list1 = new ArrayList<>();
   list1.add(new Student("zhangsan",18,0));
   list1.add(new Student("lisi",28,0));
   list1.add(new Student("wangwu",24,1));
   //这里如果add(new Teacher(...));就会报错,因为我们已经给List指定了数据类型为Student
   show1(list1);

   System.out.println("************分割线**************");

   //这里我们并没有给List指定具体的数据类型,可以存放多种类型数据
   List list2 = new ArrayList<>();
   list2.add(new Student("zhaoliu",22,1));
   list2.add(new Teacher("sunba",30,0));
   show2(list2);
}

来看看运行结果:

Student{name='zhangsan', age=18, sex=0}
Student{name='lisi', age=28, sex=0}
Student{name='wangwu', age=24, sex=1}
************分割线**************
Student{name='zhaoliu', age=22, sex=1}
Teacher{name='sunba', age=30, sex=0}

从show2方法可以看出和show1的区别了,list2存放了Student和Teacher两种类型,同样可以输出数据,所以这就是T和?的区别啦~小伙伴们了解了吧

下面来看看?的扩展写法:

List extends 数据类型> list

public static void show3(List<? extends Teacher> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

List extends Teacher> list这种写法表示可以接收Teacher和它的子类数据类型的list集合,写个测试方法show3(list2);试试:

Student{name=&#39;zhaoliu&#39;, age=22, sex=1}
Teacher{name=&#39;sunba&#39;, age=30, sex=0}

可以看到正常输出,因为集合中的数据都是Teacher的子类类型,如果我们将List extends Teacher> list改成List extends Student> list会出现什么情况?

Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?

仔细看这张图,我们新建了一个list3并且声明数据类型为Teacher,这个时候调用show3(List extends Student> list) 就马上会报错的,错误信息提示Teacher不能转换成Student,因为Student是Teacher的子类,而我们只接受Student及它的子类,所以当然会报错了。

List super 数据类型> list

这种写法表示只接收指定的数据类型及它的父类类型,也简单的写段代码看看效果:

public static void show4(List<? super Student> list) {
    for (Object object : list) {
        System.out.println(object);
    }
}

可以看出来,我们接收的是Student及它父类的集合,我们写两个集合数据然后调用试试。

List list4 = new ArrayList<>();
list4.add(new Student("sunba",30,0));
list4.add(new Teacher("zhaoliu",22,1));
show4(list4);

在list中插入了一个Student和Teacher对象,看看结果:

Student{name=&#39;sunba&#39;, age=30, sex=0}
Teacher{name=&#39;zhaoliu&#39;, age=22, sex=1}

没毛病,正常运行并输出。

下面我们来看看,如果我们是传递的 Student的子类的集合会咋样

Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?

可以看到和之前的一样,会报错,理由也是一样的,以为我们已经定义了只能接收Student及其父类的数据类型。

最后来看一种情况

如果我定义List的时候没有指定数据类型,并且插入了一个Child,Student,Teacher,还是调用show4(List super Student> list)

테스트 코드를 통해 둘의 차이점을 직관적으로 느껴봅시다:

rrreeeJava 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?실행 결과를 살펴보겠습니다:

Student{name='zhangsan', age=18, sex=0}
학생{name='lisi', 나이=28, 성별=0}
학생{name='wangwu', 나이=24, 성별=1}
***** ** ****구분선****************
학생{이름='zhaoliu', 나이=22, 성별=1}
선생님{ name='sunba', age=30, sex=0}

show2 메소드에서 show1과의 차이점을 알 수 있습니다. list2는 Student와 Teacher라는 두 가지 유형을 저장하고 데이터도 출력할 수 있으므로 다음과 같습니다. T와 의 차이점은 무엇입니까? 친구들, 한 번 알아볼까요? 확장된 쓰기 방법: Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?

List 확장 데이터 유형> 목록

rrreee

List 확장 교사> 목록 이 쓰기 방법은 교사와 그 하위 항목을 받을 수 있음을 의미합니다. 클래스 데이터 유형의 목록 컬렉션의 경우 테스트 메서드 show3(list2);를 작성합니다. 🎜rrreee🎜 컬렉션의 데이터가 모두 Teacher의 하위 클래스이기 때문에 정상적인 출력을 볼 수 있습니다. 목록 확장 교사> 목록목록으로 변경하면 어떻게 되나요? 🎜🎜<img src="https://img.php.cn/upload/article/000/465/014/168379980974599.png" alt="Java 제네릭에서 자리 표시자 T와 ?의 차이점은 무엇입니까"> 🎜 🎜이 그림을 잘 보세요. 새로운 list3을 생성하고 데이터 유형을 Teacher로 선언했습니다. 이때 <code>show3(List<?extends Student> list)를 호출하면 즉시 오류가 보고됩니다. 오류 메시지는 Student가 Teacher의 하위 클래스이기 때문에 Teacher It can be Converted to Student로 메시지를 표시하며, 우리는 Student와 그 하위 클래스만 허용하므로 당연히 오류가 보고됩니다. 🎜🎜List super data type> list🎜🎜이러한 작성 방식은 지정된 데이터 유형과 해당 상위 유형만 수신된다는 의미이며 간단히 코드를 작성하여 효과를 확인할 수도 있습니다. : 🎜rrreee🎜 우리가 받는 것은 Student와 그 부모 클래스의 컬렉션이라는 것을 알 수 있습니다. 우리는 두 개의 컬렉션 데이터를 작성한 다음 이를 호출하여 시도합니다. 🎜rrreee🎜학생 및 교사 개체를 목록에 삽입하고 결과를 확인하세요. 🎜rrreee🎜아무 문제가 없습니다. 정상적으로 실행되고 출력됩니다. 🎜🎜Student 하위 클래스 컬렉션을 전달하면 어떤 일이 일어나는지 봅시다🎜🎜무엇입니까? Java Generics에서 자리 표시자 T와 ?의 차이점🎜🎜이전과 동일하다는 것을 알 수 있으며, 오류가 보고되고 이유도 같습니다. Student만 받을 수 있도록 정의했다고 생각하면 됩니다. 및 상위 클래스의 데이터 유형. 🎜🎜마지막으로 상황을 살펴보겠습니다🎜🎜List를 정의할 때 데이터 유형을 지정하지 않고 Child, Student, Teacher를 삽입해도 여전히 show4(List super Student> list)를 호출합니다. code> , 오류가 보고됩니까? 오류가 보고되지 않으면 결과는 어떻게 되나요? 🎜🎜🎜🎜🎜list는 여러 데이터 유형을 저장할 수 있으므로 오류가 보고되지 않는 것을 볼 수 있습니다. 그러면 show4 메소드를 호출하면 결과가 어떻게 될까요? 🎜🎜🎜🎜🎜프로그램이 정상적으로 실행되고 결과가 출력되는 것을 볼 수 있습니다. 우리가 받는 것은 Student 및 해당 상위 클래스 개체 데이터 유형입니다. Child가 Student를 상속하므로 프로그램은 자동으로 Child를 상위 클래스 Student로 변환합니다. 출력에 사용되므로 모두가 주의해야 합니다. 자동으로 위쪽으로 변환됩니다. 🎜

위 내용은 Java 제네릭에서 자리 표시자 T와 의 차이점은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제