Java泛型笔记

本文详细介绍了Java泛型的入门知识,包括如何使用泛型提高代码效率,避免类型转换,以及泛型在自定义类、接口、方法和继承中的使用规则。
摘要由CSDN通过智能技术生成

泛型入门

public class Generic_ {
    public static void main(String[] args) {
        // 创建ArrayList
        ArrayList arrayList = new ArrayList();
        // 添加对象
        arrayList.add(new Dog("大黄", 3));
        arrayList.add(new Dog("小黄", 1));
        arrayList.add(new Dog("旺财", 2));
        // 遍历
        for (Object o : arrayList) {
            // 先向下转型,再输出
            Dog dog = (Dog)o;
            System.out.println(dog.getName() + "-" + dog.getAge());
        }
        // 传统方法,不能对加入到集合的数据类型进行约束
        // 集合中可以加入Dog类,也可以加入Cat类等,这样在遍历时就产生的问题(需要先将对象向下转型为对应的类)
        // 遍历的时候需要进行类型转换,数据量较大的时候,对效率有影响。

        // 加入泛型,再创建集合
        ArrayList<Dog> dogs = new ArrayList<>();
        // 只能添加Dog类,添加其他类时会报错
        dogs.add(new Dog("大黄", 3));
        dogs.add(new Dog("小黄", 1));
        dogs.add(new Dog("旺财", 2));
        // 遍历
        for (Dog dog : dogs) {
            // 不需要向下转型了
            System.out.println(dog.getName() + "-" + dog.getAge());
        }

        // 区别:
        // 不使用泛型: Dog-加入 --> Object-取出 --> Dog
        // 放入到ArrayList会先转为Object,再取出时,还需要转换为Dog
        // 使用泛型: Dog --> Dog --> Dog; 放入取出不需要转换类型,提高效率。
    }
}

class Dog{
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

泛型细节

1. <E>    <T>,,,,,,,,,E或T只能是引用类型,不能是基本类型。例如,Integer可以,int不可以

2. 在指定泛型具体类型后,可以传入该类型或其子类型。

3. HashSet<Student> students = new HashSet<Student>(); 可简写为

        HashSet<Student> students = new HashSet<>();

4. 若不指定泛型,则默认是Object类泛型。

自定义泛型类

自定义泛型接口

public class CustomGeneric {
    public static void main(String[] args) {
        Pig<String, Integer, Double> stringIntegerDoublePig = new Pig<String, Integer, Double>("qing", 12, 23.2);
    }
}

// 自定义泛型类
// 普通成员可以使用到泛型
// 使用泛型的数组,不能初始化
// 静态方法不能使用类的泛型
// 泛型类的类型,实在创建对象时确定的(因为创建对象时,需要指定确定类型)
// 如果在创建对象时,没有指定泛型,则默认为Object
class Pig<T, R, M>{
    T t; //属性使用到泛型
    R r;
    M m;

    public Pig(T t, R r, M m) { // 构造器使用到泛型
        this.t = t;
        this.r = r;
        this.m = m;
    }

    public T getT() {// 返回类型使用到泛型
        return t;
    }

    public void setT(T t) {// 方法使用到泛型
        this.t = t;
    }

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }
}

interface A<T, R>{
    // 自定义泛型接口
    // 1. 接口中,静态成员不能使用泛型
    // 2. 泛型接口的类型,在继承接口或实现接口时确定
    // 3. 没有指定类型,默认为Object
    //T t; //错误,因为接口中的属性默认修饰符时 public final static, (方法默认修饰符是 public abstract)
}

自定义泛型方法

基本语法: 

修饰符<T,R...> 返回类型  方法名(参数列表)

注意细节:

1. 泛型方法可以定义在普通类中,也可以定义在泛型类中

2. 当泛型方法被调用时,类型会确定

3. public void eat(E e){ }      修饰符后面没有<T,R...>,  eat方法不是泛型方法,而是使用了泛型

public class CustomGenericMethod {
    public static void main(String[] args) {
        Car car = new Car();
        car.fly("wxl", 123);// 当调用方法,传递参数,编译器会自动确定类型
        Phone<String> stringPhone = new Phone<>();
        stringPhone.call(123, "xiaomi");
    }
}

class Car{// 普通类
    public void run(){// 普通方法
        
    }
    public <T,R> void fly(T t, R r){ //泛型方法

    }
}

class Phone<E>{// 泛型类
    public <T> void call(T t, E e){// 泛型方法
        
    }
}

泛型的继承与通配符

public class GenericExtend {
    public static void main(String[] args) {
        // List<Object> strings = new ArrayList<String>(); // 错误,泛型不具备继承性
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();

        printCollection1(list1);
        printCollection1(list2);
        printCollection1(list3);
        printCollection1(list4);
        printCollection1(list5);
        // 说明List<?> 表示任意的泛型都能接受

       // printCollection2(list1);  // 错误
       // printCollection2(list2);  // 错误
        printCollection2(list3);
        printCollection2(list4);
        printCollection2(list5);
        // 说明List<? extends AA> 只接受AA 及AA的子类

        printCollection3(list1);
       // printCollection3(list2);  // 错误
        printCollection3(list3);
       // printCollection3(list4);  // 错误
       // printCollection3(list5);  // 错误
        // 说明List<? super AA> 只接受AA 及AA的父类
    }
    public static void printCollection1(List<?> c){
        for (Object object : c) {

        }
    }
    public static void printCollection2(List<? extends AA> c){

    }
    public static void printCollection3(List<? super AA> c){

    }
}

class AA{

}
class BB extends AA{}
class CC extends BB{}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值