Java 泛型

要记住,泛型是为容器设计的,虽然泛型不仅仅只能用在容器设计上。在脑海中具象化的时候一定要有这个概念。

泛型,意思是类型参数化,类型是可变的。

泛型能够做的什么?

1. 参数的类型检查

编译器会检查参数的类型是否符合泛型。

2. 覆盖时自动创建桥方法适配

底层是Object或者限定边界,在重写的时候使用的具体类型,所以自动生成一个桥方法,使用底层参数类型,内部调用具体实现的具体参数类型的方法,来实现覆盖保证多态。

3. 调用后类型强制转换

可以利用泛型语法,让编译器在调用泛型方法或者属性的语句加上类型强制转换。

4. 实现多参数之间的类型关系

让多个参数只要是同一类型,

泛型语法

类与方法的类型参数定义

泛型有两种,类的泛型,和方法的泛型。

类泛型通过 class ClassName<T>来定义,泛型参数在类作用域中都可以使用

方法泛型就像这样 public static final <T> void methodName(T t)定义,在方法的参数上

传递类型

传递给类,传递给方法

传递给类只能显式传递,通过实例化时的<>,来传递具体的类型名

传递给方法只能隐式传递,通过具体参数,传递参数所属类型

通配表达

三个符号:?extends super

使用?只是为了不将具体类型传递给类型参数,也就是不需要的情况。所以类型变量完全可替代通配符?。

只有具体类型可以实例化泛型类。

可以创建通配泛型变量,来引用其可包含的具体泛型类实例。

extends和无限制通配泛型变量无法执行修改(写)操作,原因是同一个父类的子类,相互不兼容,在不知道内部具体的泛型之前,很可能导致修改类型和内部泛型不一致,所以这种操作直接禁止。

而super通配泛型变量可以执行写操作,因为super所代表的内部具体类型的泛型类,一定是父类,所以修改的类型一定属于内部泛型的子类,那么子类可以上转型到父类,就允许操作。

传递泛型的语法,可以让具体类型从通配泛型变量中传递给方法的泛型参数,从而通过方法的具体类型泛型变量来执行修改。

        private static <T> void swapInternal(DynamicArray<T> arr, int i, int j){
            T tmp = arr.get(i);
            arr.set(i, arr.get(j));
            arr.set(j, tmp);
        }
        public static void swap(DynamicArray<? > arr, int i, int j){
            swapInternal(arr, i, j);
        }

通配表达可以用在泛型类的定义上,也可以用在创建一个泛型变量上(而不是实例化)。

例如定义:

class MyClass< T extends Number>{

...

}

例如实例化:

MyClass<? extends Number> myClass = new MyClass<Integer>();

局限性

基本数据类型不能作为实例化类型参数(但在自动装箱机制下解决,只在<>中无法使用基本数据类型的类型名)。

运行时类型信息不适用于泛型(因为类型擦除,被Object或者它们的限定边界来替换

关于类型判断

因为类型擦除,对泛型对象的类型,和原始类型相同。

如果A<T extends Comparable>,那么编译后就会用Comparable代替。

所以不会因为不同的类型参数,导致对象的类型不同。但是instanceof语法有变,仅支持无限定通配符版的类型作为instanceof的判断类型。

支持if(p1 instanceof Pair<? >) 而不支持 instanceof Pair<Interger>等具体的类型参数。

重载的反常识

因为类型擦除的关系,只要泛型类的原型是同一个,那么就是同一类型,无法构成重载。

多态问题

我们知道,为了实现多态,编译器会生成桥方法。

但是对于无参数类型的方法,会导致

如果想重写父类实现的泛型接口,在编译器和底层实现上会出现冲突。

实际上重写的方法都是Object底层参数,而想要不同的类型参数,也就是不同的类型检查。这样会导致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值