泛型
- 定义:类和方法在定义时类型不确定,只有在具体使用时才能确定类型
- 作用:泛型是编译器的一种保护作用,用来解决类型转换间的安全隐患;在两个毫无关系的类发生强转时会产生运行时异常,为了能在编译时就能检测出来,因此引入了泛型。
- 语法表示:< T >, <>表示泛型,T表示类型参数,T可以指定为不包括基本类型的任意类型。
- 注意:引用泛型后,一个泛型类的类型在使用时已经确定好,无需向下转型。
- 泛型类:在类中使用泛型:
- t和a是一个类型
class MyClass<T> {
private T t;
private T a;
}
2.泛型类可以接收多个参数类型
t和a不是一个类型,下面人为的定义参数类型是T,返回类型是E
class MyClass<T,E> {
private T t;
private E a;
}
class Test{
public static void main(String[] args){
MyClass<String,Integer> class1 =
new MyClass<String,Integer> ();
//JDK1.7以后后面的尖括号里不用写类型
//MyClass<String,Integer> class1 = new MyClass<>();
}
}
- 泛型方法:泛型方法可以脱离泛型类存在,方法中的类型与类中的类型无关,泛型类中的方法也不一定就是泛型方法,还有可能是成员方法,按照一定语法规则写的方法才是泛型方法。
1.语法:类型参数是写在返回值前面的
返回值:void
class MyClass{
public <T> void fun(T t){
System.out.println(t);
}
}
2.返回值也可以是声明的类型参数
第一个T表示这个方法是一个泛型方法
第二个T表示这个方法的返回值类型
第三个T表示参数的类型
public <T> T fun(T t){
System.out.println(t);
}
3.当泛型类中有泛型方法时要注意不要混淆
泛型方法的返回值的类型的T(第二个T)和泛型类中的T不是一个T
避免混淆方法:两个类型用不同的大写字母表示,不要重名
注意:泛型类中的属性的类型一定和类的类型一样
//不好的写法,容易混淆
class MyClass<T>{
private T t;
public <T> T fun(T t){
System.out.println(t);
}
}
//好的写法,不要重名
class MyClass<T>{
private T t;
public <M> M fun(M t){
System.out.println(t);
}
}
public class Test {
public static void main(String[] args) {
MyClass<String> myClass = new MyClass<>();
myClass.testMethod1("hello 泛型类");
//类的类型是String
Integer i = myClass.testMethod2(100);
//而方法中传的参数是Integer,
//所以泛型参数的类型与泛型类的参数是无关的
System.out.println(i);
}
}
- 泛型接口:接口一定要有子类
interface ISubject<T>{
void fun(T t);
}
子类在实现接口时有两种方式:
1.在实现接口时就确定好接口的类型
class SubjectImpl implements ISubject<String>{
@Override
public void fun(String s) {}
}
2.子类实现接口时保留泛型,子类也是泛型类:
实现的方法的泛型参数类型和泛型类类型一样
class SubjectImpl<T> implements ISubject<T>{
@Override
public void fun(T s) {}
}