美文网首页
九、泛型

九、泛型

作者: blank_white | 来源:发表于2020-07-19 20:58 被阅读0次

九、泛型

        
        List<String> list=new ArrayList<String>();
        // JaveSE 7 以后的版本 后面构造函数里的 String 可以省略        
        List<String> list2=new ArrayList<>();

尽量不要写这种有能与泛型方法重载的代码,有迷惑性

package org.example;

public class Genericity<T> {

    public static String prU(String s){
        System.out.println("普通方法"+s);
        return null;
    }

    public static <U>  U prU (U u){
        System.out.println("泛型方法"+u);
        return null;
    }

    public static void main(String[] args) {
        Genericity.prU(6);
        Genericity.prU("string");
        Genericity.<String>prU("string");
    }
}
// 打印结果
// 泛型方法6
// 普通方法string
// 普通方法string

限定传入 T 的类型


// 
// Java 是单继承类,多实现接口,所以 T 最多能被限定为一个类的子类,可以限定为实现多个接口
// 限定 T 是 xx 的子类,这个 xx 要放在最前面,类和多个接口之间用 & 分隔
// 多个泛型类之间用 , 隔开

public class Genericity<T extends Animal & Comparable &Serializable, S extends Person> {

}

泛型数组

Java 不支持泛型类型的数组

通配符

Pair<? super Employee> pair :带有超类型限定的通配符可以向泛型对象写入
Pair<? extends Employee> pair :带有子类型限定的通配符可以从泛型对象读取
Pair<?> pair :无限定通配符 get返回值只能赋给 Object , set 方法不能被调用

package org.example;

import org.example.domain.Employee;

public class Pair<T> {

    T first;
    T second;
    
    /// 这里解释的有些混乱 ,下面还有一个解释

    // 传入参数 pair 的泛型 T 是 Employee 的子类, pair.getFirst 将返回一个 Employee 的子类 T ,可以用 Employee类型接收 ,也因此能使用 Employee 的方法
    // 但是 setFirst( T ) 的参数需要传入一个 T 的子类,无法保证
    static void print(Pair<? extends Employee> pair){
        
        // 比如传入了参数是这样声明的  Pair<EmployeeSon> pair  = new Pair<>();  
        // 那么 get方法的声明就会变成  EmployeeSon getFirst()
        Employee e=pair.getFirst();
        e.getName();
        
        // 那么 set方法的声明就会变成  void setFirst( EmployeeSon e)
        // 但是你无法提前预知 EmployeeSon ,没法保证传入的就一定是 EmployeeSon 的子类
        // pair.setFirst( xxx )
    }

    // 传入参数 pair 的泛型 T 是 Employee 的父类 
    // setFirst(T ) 只要传入 Employee 及子类,则一定能满足条件
    // 但是 getFirst() 的返回值为类 T ,只有最高的 Object o= T()
    static void print2(Pair<? super  Employee> pair){
        
        // 比如传入的参数是这样声明的  Pair<EmployeeFather> pair = new Pair<>();
        // 那么 set方法的声明就会变成  void setFirst( EmployeeFather e)
        pair.setFirst(new Employee());
        
        // 那么 get方法的声明就会变成  EmployeeFather getFirst()
        // 但是你无法提前预知 EmployeeFather ,没法保证用来接收的类一定是EmployeeFather的父类,除了 Object类
        // Employee e=  pair.getFirst(); // 返回的是 EmployeeFather 类型 会出错 
        
        // 虽然接收了,但是后续拿来干什么?没有意义
        Object o=pair.getFirst();
    }

    //
    static void print3(Pair<?> pair){
        //pair.setFirst(new Object());  // 出错 set 方法不能调用
        //pair.setFirst(new EmployeeSon()); // 出错
        //Employee e= pair.getFirst(); // 返回的 Object 类型 会出错 
    }
    
    public static void main(String[] args) {

        Pair<Object> pair = new Pair<>();
        print(pair); // 报错
        print2(pair);
        
        Pair<EmployeeSon> pair2 = new Pair<>();
        print(pair2);
        print2(pair2); // 报错
    }


    public T getFirst() {
        return first;
    }

    public void setFirst(T first) {
        this.first = first;
    }

    public T getSecond() {
        return second;
    }

    public void setSecond(T second) {
        this.second = second;
    }
}

? super ?extends 看这里 ↓↓↓↓↓↓↓↓↓

    

    static void print(Pair<? extends Employee> pair){
        
        T t1=pair.getFirst();
        // 因为 T 是 Employee 的子类,所以下面的代码是没问题的
        Employee e=t1;
        e.getName();  
        
        // 这里 A 类需要是 T 的子类,需要找到一个具体的类A,确保 A 一定是 T 的子类,
        // 没有办法保证,所以无法使用 set 方法
        T t2=new A(); 
        pair.setFirst(t2 )
    }



    static void print2(Pair<? super  Employee> pair){  
        // T 是 Employee 的父类,所以下面的代码一定没问题
        T t1= new EmployeeSon();
        pair.setFirst(t1);
        
        T t2=pair.getFirst();
        // 需要 A 是 T 的父类,需要找到一个具体类 A,确保 A 是 T 的父类,
        // 无法保证,除了 Object 类,
        // 用 Object 接收了也没什么意义,所以说无法使用 get 方法
        A a=t2;
    }


相关文章

网友评论

      本文标题:九、泛型

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