为什么需要泛型
如果为每一种类型都写一个类来适配,会造成code冗长且难读,所以需要写一个同一的抽象的方法来实现,并让编译器自动的传入这些类型。
如何实现
- 通常放在类后面的尖括号里
public class Genertic <K> {}
- 也可以指代多个
public class Genertic <K, V> {}
这个类中的变量都可以用K和V来表示了
- 泛型不仅可以应用在类中,也可以应用在单独的方法中
public <K> K maxGet(K key) {}
这个方法中的K变量都会转换成你传入的数据类型
技术细节
泛型数组
注意:
java如果直接创造一个泛型类型的数组,会直接报错`
解决方法:K[] kList = (K[])new object();
将其强制转换为泛型类
泛型类型实现接口
格外还有提到的一点是,泛型类型是可以实现接口的
public <K extends Comparable<K>> K getMax(K a,K b) {
return compareTo(b);
}
这段代码的意思是接受K类型的a和b参数,返回较大的一个,因为不确定k的具体类型,比较就变得尤为困难。
所以这里用到了comparable接口,用他的comparaTo这个方法来进行自然排序。
这里的extends并不是通常意义上的extends
通常extends是继承方法 或者 接口继承接口
这里更像是一种类型限制为类型参数施加了限制,必须是compareTo实现了的类型
若直接使用compareTo而不extends,编译器会直接报错,因为无法确认K是否是compareTo已经处理了的类型,“保守的”编译器会直接报错
接收参数
还有重要的一点是,泛型,传给这个K的只能是引用类型(referene),不能用于基本数据类型(int,char,double),只能传入Integer,List,String
等类型(int等类型的包装形式)
Integer占用的空间要比int大得多(object+reference+data)
问题:我传入的是int a = 5,但是K是Integer是怎么回事?
java的编译器会自动地装箱和拆箱,传入的一个int,就会自动装箱成Integer.
注意
:数组是不能自动装箱的
digress:java还会自动的加宽:例如int转成double,但double转成int需要cast强制转换
小结
泛型编程极大的方便了对不同变量的处理,优化了代码的可读性,和美观,也减少了大量的重复工作,还增加了代码的安全性(如果没有泛型编程,通常会充斥着各种强行的cast强制转换)。