1:泛型的定义
泛型是指参数化类型的能力,通俗来说就是用参数的形式替换java类型的一种手段。java中可以定义带泛型的类和方法,然后在编译无误之后编译器将会用具体类来替换参数类型。 泛型类型必须是引用类型,不能使int.、char这种
2:泛型的优点
1)在编译时检测出错误,而不是在运行时检测出错误(在编译时,将检测类型是否匹配,总的来说就是解决原始类型的一些类型不匹配的问题在编译的时候给检测出来了)
2)可以减少很多重复的代码,类似和java中继承的一些作用
3:如何定义泛型类、接口、方法
a)泛型类和泛型接口
package com.cqut.generic;
public class GenericClass<T> {
public GenericClass(){ //注意构造函数不需要写GenericClass<T>
}
public T delete(T obj) {
return obj;
}
}
package com.cqut.generic;
public interface GenericInterface<T,T1,T2> {
public T doSomething(T1 a,T2 b);
}
b)泛型方法
package com.cqut.generic;
public class GenericClass {
public static <T> void doSomething(T s){
}
}
这是泛型方法的定义,用的话就是GenericClass.<Integer>doSomething(1);
写到这里,我们可以看到上面看到在上面定义的泛型类也有方法,注意两个的区别,类上的方法是对定义的泛型的应用(可以这么理解吧,可以看到定义的泛型类的方法上没有<T>,而泛型方法上就有这个了,可以说泛型的定义就是这么个<T,T1,T2>)
4:通配泛型
原始类型:不使用类型参数的泛型类称为原始类型,主要是为了兼容以前的程序,毕竟泛型在1.5才出来
要说通配泛型,则必须要知道这么个东西,尽管Integer是Number的子类型,但是ArrayList<Integer>不是ArrayList<Number>的子类型,假设这样设计的话,java泛型就达不到很好的继承这些的效果了,所有出现了通配泛型,有三种形式
a)非受限通配ArrayList<?>,这个和ArrayList<? extends Object>是一样的
b)受限通配 ArrayList<?extends Number>这类
c)下限通配 ArrayList<? super Integer>
5:泛型类型消除
简单来说,泛型只存在编译时,一旦编译器认为泛型类型是安全的,就会把它换成原始类型,所以在运行时,泛型是不存在的,就是说ArrayList<String>和ArrayList<Number>都是ArrayList的实例,而不存在ArrayList<String>和ArrayList<Integer>这类东西在运行时候
因为泛型类型消除,所以存在泛型应用的一些限制
a)不能使用new E()
b)不能使用new E[ ];,但是可以使用强转进行创建数组 E[] elements=(E[])new Object[10],同样a中也可以;
c)在静态环境下不允许类的参数是泛型类型,因为泛型类的所有实例都是相同的运行类,所有静态变量和方法 代码块都是被所有实例共享的,假设可以的话 每个实例都想把静态变量的类型改为自己的类型,这是不可能的,所以是不允许的
d)异常类不能是泛型(异常是运行时候的,但是泛型在编译之后就没有了)