Java 学习笔记(十一)

本文详细介绍了Java中的泛型,包括泛型的概念、作用、声明与使用,以及自定义泛型类和方法。此外,还探讨了泛型的继承、通配符的使用,如? extends 和 ? super 的限制。通过示例代码,展示了泛型在实际编程中的应用,帮助读者深入理解泛型提高代码类型安全性的功能。
摘要由CSDN通过智能技术生成

泛型

泛型就是可以接受数据类型的数据类型

  • 泛型是参数化类型,用来解决数据类型的安全性问题
  • 在类声明或者实例化的时候只要指定好具体的类型即可
  • 泛型保证了程序在没有编译警告的时候,就不会出现 ClassCastException

泛型的作用,就是在类声明的时候通过一个标记表示类中某个属性的类型,或者是某个方法的参数 / 返回值类型

如:

class Person<E> { 	// 声明泛型
	E s;	// 声明泛型类型的参数
	
	public Person(E s){
		this.s = s;
	}
	
	public E fun() {
		return this.s; 
	}
}

如果初始化的时候,有语句:Person<String> p = new Person<String>("456");
那么刚刚的类就可以理解为:

class Person { 	// 声明泛型
	String s;	// 声明泛型类型的参数
	
	public Person(String s){
		this.s = s;
	}
	
	public String fun() {
		return this.s; 
	}
}

泛型声明

interface<T> {}
class<K, V> {}

其中, T、K、V 不代表值,而是表示类型。这里用任意字母都可以

泛型使用

List<Integer> list = new ArrayList<>();
List<Integer> list2 = new ArrayList<Integer>();	// 简写
// List<int> list = new ArrayList<>();	// 不能使用基本类型
  • 在指定泛型具体类型后,可以传入该类对象,或者子类对象
  • 如果不指定泛型类型,那么默认就是 Object

自定义泛型

注意

  • 普通成员(属性、方法)可以使用泛型,静态成员不可以使用
  • 使用泛型的数组不能初始化
  • 静态方法中不能使用类的泛型
  • 泛型类的类型,在创建对象的时候确认(创建的时候需要指定)
  • 泛型接口的类型,在继承或者实现的时候指定。由于接口的属性都属于静态类型,所以接口中不可以定义泛型属性
  • 创建对象时未指定,默认 Object

例子:

// T R M 是泛型标识符
class Tiger<T, R, M> {
    String name;

    // 普通成员属性可以使用泛型
    R r;
    M m;
    T t;
//    泛型数组不能初始化,因为数组 new 的时候无法确定 T 的类型,就无法在内存开辟空间
//    T[] arr = new T[5];
    T[] arr;    // 可以定义

//    静态属性不能使用泛型,因为静态属性是在类加载的时候创建的,此时对象并未创建
//    也就是此时没有指定类型,那么静态属性也就无法确定自身的类型,不能创建
//    static R r2;

    public Tiger(String name, R r, M m, T t) {
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    // 普通方法使用泛型
    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;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

自定义泛型方法

语法:

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

例子:

// 例子
class Car{
	public <T, R>void func(T t, R r){ // 泛型方法
		System.out.println(t.getClass());
		System.out.println(r.getClass());
	}
}

// 调用
public static void main(String[] args) {
	Car car = new Car();
	car.func(300, "666");	// 泛型会自动装箱成对应的类型
	car.func("6666", 666);	// 泛型会自动装箱成对应的类型
}

注意:

  • 泛型方法可以定义在泛型类中,也可以定义在普通类中
  • 泛型方法被调用时,类型会确定
  • public void eat(E e) {} 这种不是泛型方法,因为修饰符后没有 <T, R…>,这是使用了泛型,一般是使用类声明的泛型
  • 泛型方法可以使用类声明的泛型(泛型方法的泛型标识符与类的一致),也可以自己声明(泛型方法的泛型标识符与类的不一致

泛型的继承和通配符

  • 泛型不具备继承性 List<Object> list = new ArrayList<String>(); // 是错误的
  • <?> :支持任意泛型类型
  • <? extends A> :支持 A类及其子类,规定了泛型的上限
  • <? super A> :支持 A类及其父类,规定了泛型的下限

例子:

public class CustomGenericTest01 {
    public static void main(String[] args) {
        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<>();
        
        // 都可以执行
        print(list1);
        print(list2);
        print(list3);
        print(list4);
        print(list5);
        
//        extendsTest(list1); 不可以执行,非 AA及其子类
//        extendsTest(list2); 不可以执行,非 AA及其子类
        extendsTest(list3);
        extendsTest(list4);
        extendsTest(list5);
        
        superTest(list1);
//        superTest(list2); 不可以执行,非 AA及其父类
        superTest(list3);
//        superTest(list4); 不可以执行,非 AA及其父类
//        superTest(list5); 不可以执行,非 AA及其父类
    }

    public static void print(List<?> list) {
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
    
    public static void extendsTest(List<? extends AA> list) {
        System.out.println("666");
    }

    public static void superTest(List<? super AA> list) {
        System.out.println("7777777");
    }
}
class AA {
    
}

class BB extends AA{
    
}

class CC extends BB {
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值