java基础---泛型机制

  • 从java5 开始增加泛型机制,用于明确集合中可以放入的元素类型,只在编译时期有效,运行时不区分是什么类型。
  • 格式:<数据类型>
  • 泛型的本质是参数化类型,让数据类型作为参数传递,E相当于形参,泛型中可以有多个类型参数<E, T, .. >

一、自定义泛型

  • 自定义泛型类
    • 实例化泛型类时需指定具体数据类型,并且是引用数据类型
    • 父类有泛型,子类可以选择保留、指定、增泛型类型
    • 继承
  • 自定义泛型方法
    • 输入参数为泛型参数,使用时需要对泛型参数实例化
    • 格式: 【访问权限】<泛型> 返回值类型 方法名(【泛型标识 参数名】){方法体;}
    • 在静态方法中使用泛型参数时,需要把静态方法定义为泛型方法,否则还未实例化就可以通过静态方法调用,则泛型类型不可得知
public class Person<T> {
    private String name;
    private T gender;
    private int id;

    public Person(String name, T gender, int id) {
        this.name = name;
        this.gender = gender;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public T getGender() {
        return gender;
    }

    public void setGender(T gender) {
        this.gender = gender;
    }

    public int getId() {
        return id;
    }

    public Person() {
    }

    public void setId(int id) {
        this.id = id;
    }
}

public class SubPerson <K,T> extends Person<T>{
    //public class SubPerson <T> extends Person<T>{   //保留父类泛型
    //public class SubPerson extends Person<String>{      //不保留父类泛型,指定父类泛型类型String
    //public class SubPerson  extends Person{ //不保留父类泛型,不指定父类泛型类型,默认Object
    public SubPerson(String name, T gender, int id) {
        super(name, gender, id);
    }

    public SubPerson() {
    }

    //泛型方法
    public <T1> void print(T1[] arr){
        for ( T1 tt:arr) {
            System.out.println(tt);
        }

    }
}

public class PersonTest {
    public static void main(String[] args) {
        SubPerson<String,Boolean> s1=new SubPerson<>();
        s1.setGender(true);
        s1.print(new Integer[]{1,2,3});
    }
}

二、通配符

  • 无限制通配符?:可以传入任意类型的参数,可以转换获取,不能添加
  • <? extends E> 表示类型的上界是E,只能是E或者是E的子类。
  • <? super E> 表示类型的下界是E,只能是E或者是E的父类。
import java.util.LinkedList;
import java.util.List;

public class GenericTest {

    public static void main(String[] args) {
        List<Person> l1=new LinkedList<>();
        l1.add(new Person("ZHANFEI",2,3));
        List<SubPerson> l2=new LinkedList<>();

        // l1=l2;  类型之间不具备父子类关系,不能强转
        //使用通配符完成类型转换,?表示任意类型
         List<?> l3=new LinkedList<>();
         l3=l2;
         l3=l1; //可以发生List<SubPerson>到List<?> 的转换

        //使用无限制通配符
        //向公共父类添加元素不能成功,因为转成了任意类型,所以添加元素类型任意,不能有保障
        //boolean add = l3.add(new Person<String>());//Change variable 'l3' type to 'List<Person<String>>'
        // 可以向公共父类获取元素,只要集合不为空
        System.out.println(l3.get(0));//Person{name='ZHANFEI', gender=2, id=3}

        //使用有限制通配符
        //<? extends Person>支持获取,不支持添加
        List<? extends Person> l4=new LinkedList<>(); //存放person及person的子类,上限是Person,所有规定类型可以是子类,不能超过person类
        //l4.add(new SubPerson("ZHANFEI",2,3));//不能添加person的子类,因为如果存放的都是SubPerson的子类,那么SubPerson类就放不进去了
        //l4.add(new Person("ZHANFEI",2,3));//不能添加person,因为如果存放的都是SubPerson,那么Person 类就放不进去了
        //l4.add(new Object());//不能添加person的父类
        Person person = l4.get(0);//获取时全部按person接受,即父类的引用指向多种子类

        //<? super Person>支持获取和添加
        List<? super Person> l5=new LinkedList<>(); //person及person的父类,指定类型最低是person类,可以通过多态使用person父类类型的引用指向person子类
        l5.add(new SubPerson("ZHANFEI",2,3));//可以添加person的子类,可以转换成person
        l5.add(new Person("ZHANFEI",2,3));//可以添加person
        //l5.add(new Object());//不能添加person的父类,超过了person类型的范围
        Object object = l5.get(0);//获取时全部按Object接受,即父类的引用指向多种子类,因为不知道存放的是Person的那些子类
    }
}

 

 




posted @ 2021-03-16 11:02  forever_fate  阅读(122)  评论(0)    收藏  举报