Java 泛型详细教程
1、泛型的产生
我们先来看一个例子:
我有一个Student学生类,他有两个属性分别用于存放javaEE,Linux课的考试成绩,可是考试成绩可能是整数,也可能是浮点数,为了解决这个问题,就将javaEE、Linux的成绩用Object类型来表示
接下来我就在测试类中测试以上的Student类
你会发现使用Object类型来表示成绩,会有以下几点缺点:
1、类型丢失(原有的double、integer类型都统一变为Object)
2、要便回原有类型需要强制转化
3、在强制转化的时候需要手动的进行类型的检查
以上出现的情况就催生出了泛型,在学习泛型之前我希望你能够始终记住一句话:
泛型始终是用来代表类型的,它在编译时确定具体类型
2、泛型的使用位置
1、泛型修饰类
2、泛型修饰接口
3、泛型方法
泛型方法的修饰符始终在方法返回值前面
4、泛型属性
3、泛型的入门程序
我们还是以之前的Student为例
需要提醒的是泛型可以用任意字母表示,
但是常用T(Type)表示类型,K(key)表示键,V(Value)表示值,E(Element)表示元素
通过以上入门程序你就会发现泛型可以自动的进行类型检查,并自动的进行类型转化
4、泛型类
注意:
1、始终记住,泛型的类型检查是在编译的时候进行,泛型是在使用的时候确定具体类型
2、泛型字母不能使用在静态属性上
原因很简单,静态属性在编译的时候就必须得确定类型来开辟内存空间,而泛型是在使用的时候确定类型
3、泛型可以使用在静态方法上
5、泛型接口
1、泛型不能使用在接口的全局常量上,因为接口的全局常量为静态属性
其他使用方法和泛型类类似
这里不再赘述
6、泛型方法
1、泛型修饰方法时需要放在方法返回值前面
2、泛型方法只能访问对象的信息,不能修改对象的信息
原因也很好理解,我要修改这个对象的信息,最起码这个对象的类型得确定吧,可以我泛型方法只有在使用时才确定类型,所以就不能修改对象的信息
7、泛型子类
在了解泛型子类之前你需要知道的是:
泛型子类也是单独的一个类,它也可以自定义一些泛型类型
你会发现一下代码特别多,但不要害怕,你可以暂时先忽略它,现在我们不妨先设想一下我们使用子类时候的场景,那个时候我们是不是就要确定泛型的类型了。那么请问一个问题:父类的泛型如何初始化和确定?
答案其实很明显,父类的泛型类型需要在子类中进行声明,这样一来之后,你再来看以下的代码,基本上每个子类都会包含父类中的泛型类型,目的就是为了在为子类指定的泛型类型的时候,父类的泛型类型也能够被指定
还有一句话:就是泛型就是为了类型的抽象代表,都是为了类型来服务的
package com.maple.generic2;
public abstract class Father<T1,T2> {
T1 name;
public abstract void test(T2 name);
}
class Child1 extends Father<String,Double>{
@Override
public void test(Double name) {
String name2 = this.name;
}
}
class Child2<T1,T2> extends Father<T1, T2>{
@Override
public void test(T2 name) {
T1 name2 = this.name;
}
}
class Child3<T1,T2,T3> extends Father<T1, T2>{
T3 score;
@Override
public void test(T2 name) {
T1 name2 = this.name;
}
}
class Child4<T3>extends Father{
T3 score;
@Override
public void test(Object name) {
Object name2 = this.name;
}
}
class Child5 extends Father{
@Override
public void test(Object name) {
Object name2 = this.name;
}
}
8、泛型擦除
泛型擦除指的是在使用的时候不指定具体类型
泛型擦除时统一使用Object类型来代替泛型类型
9、泛型没有多态
有一个父类和子类
有一个测试泛型类
10、通配符?
通配符?表示类型不定
1、只能用在声明类型和声明方法参数上,不能用在声明类上,只能用在声明上,使用的时候不能使用
其实只要理解了通配符表示类型不定这几句话就可以理解了,如果用在类上,那这个类下面的的其他泛型类型也就没法确定指定类型
例如以下统配符的使用是正确的
11、通配符? extends super实现泛型多态
12、泛型的嵌套
有两个泛型类Farther和Sons,
在进行嵌套泛型的使用需要一层层拆分,具体见如下的代码
13、没有泛型数组
因为类型不定,它无法为数组开辟空间