美文网首页
泛型的区别

泛型的区别

作者: c3e1ce81199b | 来源:发表于2018-12-06 23:05 被阅读0次

    一直以来,泛型的使用都是个迷,特别是<?>和<T>更令人疑惑
    现在来揭开谜团
    来看例子

    /**
     只有声明<T>才是泛型方法,其位置在修饰符和返回值之间
    */
    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);
        }
    }
    

    上述方法说明,泛型方法在使用时,能确定泛型是同一种,而<?>可以定义泛型是多种

    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);
    }
    

    直观感受...

    泛型可用于泛型类泛型接口泛型方法,其中泛型方法是比较难理解的...

    /**
     * 泛型方法的基本介绍
     * @param tClass 传入的泛型实参
     * @return T 返回值为T类型
     * 说明:
     *     1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
     *     2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
     *     3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
     *     4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
     */
    public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
      IllegalAccessException{
            T instance = tClass.newInstance();
            return instance;
    }
    Object obj = genericMethod(Class.forName("com.test.test"));
    
    
    public class GenericFruit {
        class Fruit{
            @Override
            public String toString() {
                return "fruit";
            }
        }
        class Apple extends Fruit{
            @Override
            public String toString() {
                return "apple";
            }
        }
        class Person{
            @Override
            public String toString() {
                return "Person";
            }
        }
        class GenerateTest<T>{
            public void show_1(T t){
                System.out.println(t.toString());
            }
            //在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。
            //由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。
            public <E> void show_3(E t){
                System.out.println(t.toString());
            }
            //在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。
            public <T> void show_2(T t){
                System.out.println(t.toString());
            }
        }
        public static void main(String[] args) {
            Apple apple = new Apple();
            Person person = new Person();
    
            GenerateTest<Fruit> generateTest = new GenerateTest<Fruit>();
            //apple是Fruit的子类,所以这里可以
            generateTest.show_1(apple);
            //编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person
            //generateTest.show_1(person);
    
            //使用这两个方法都可以成功
            generateTest.show_2(apple);
            generateTest.show_2(person);
    
            //使用这两个方法也都可以成功
            generateTest.show_3(apple);
            generateTest.show_3(person);
        }
    }
    

    较为详细的引用地址:https://www.cnblogs.com/icebutterfly/p/9012858.html

    相关文章

      网友评论

          本文标题:泛型的区别

          本文链接:https://www.haomeiwen.com/subject/qwnacqtx.html