泛型
参数化类型:ParameterizedType
集合泛型
- 集合中泛型的应用:通过指定泛型的数据类型,限制集合存储的元素的数据类型
泛型的原理
-
泛型的绑定:
在创建类对象时,指定了泛型的具体类型;在编译时,检查数据类型是否符合泛型的要求;如果不符合,编译报错
-
泛型的擦除
当编译检查类型没问题时,编译完成后,泛型会被擦除
注意:泛型仅仅是在编译期进行类型的强制检查;但当真正运行时,泛型已经被擦除掉
自定义泛型
-
类上定义泛型
// 1. 定义一个泛型 class 类名<泛型名称> extends 父类{} // 2. 可以定义多个泛型 class 类名<泛型1,泛型2,…> extends 父类{}
-
泛型名称:符合标识符的命名规范均可,编译运行不会报错;但是一般会通过一个大写字母,代表一个泛型;T(type) E(element) K(key) V(value)
-
如何使用该泛型?
-
可以指定属性的数据类型
-
可以作为方法的返回值数据类型
-
可以作为方法的参数列表中的数据类型
-
示例:
public class FXDemo1 { public static void main(String[] args) { Paper<String> p = new Paper<String>(); p.setContent("hello world"); System.out.println(p.getContent()); } } class Paper<E>{ private E content; public E getContent() { return content; } public void setContent(E content) { this.content = content; } }
-
-
接口上定义泛型
// 1. 定义一个泛型 interface 接口名<泛型名称>{} // 2. 可以定义多个泛型 interface 接口名<泛型1,泛型2,…>{}
-
类似于类上定义泛型
-
可以定义多个泛型
public class FXDemo2 { public static void main(String[] args) { // new InterImpl().method("123"); new InterImpl<String>().method("123"); } } interface Inter<T>{ public void method(T num); } // 创建类时绑定泛型 //class InterImpl implements Inter<String>{ // @Override // public void method(String value) { // System.out.println(value); // } //} // 创建对象时绑定泛型 class InterImpl<T> implements Inter<T>{ @Override public void method(T value) { System.out.println(value); } }
-
-
方法上定义泛型
public <T> T method(T t){ return t; }
示例:
public class FXDemo3 { public static void main(String[] args) { Demo d = new Demo(); String s = d.method("abc"); Demo1 d1 = d.method1("abc",100); System.out.println(s+","+d1.getT1()+","+d1.getT2()); } } class Demo{ private String str; public<T> T method (T t){ // public<T> T method (T t){ // 泛型的定义 返回值类型 参数类型 return t; } public <T1,T2> Demo1 method1 (T1 t1, T2 t2){ Demo1<T1,T2> d1= new Demo1<T1,T2>(); d1.setT1(t1); d1.setT2(t2); return d1; } } class Demo1<T1,T2>{ private T1 t1; private T2 t2; public T1 getT1() { return t1; } public void setT1(T1 t1) { this.t1 = t1; } public T2 getT2() { return t2; } public void setT2(T2 t2) { this.t2 = t2; } }
泛型的通配 (很少用)
-
通过 ? 来表示泛型的类型暂时还不确定,直到具体类型传入时,会将 ? 和具体类型绑定;
public class FXDemo4 { public static void main(String[] args) { method(new Demo2<String>()); method(new Demo2<Integer>()); } public static void method(Demo2<?> d){ // d.setField("abc"); // error 无法将具体类型和?绑定 System.out.println(d.getField()); // 可以绑定任意传入的类型 } } class Demo2<T>{ private T field; public T getField() { return field; } public void setField(T field) { this.field = field; } }
泛型的上限和下限
- 泛型上限:? extends 类名 — 传递的要么是该类本身要么是该类的子类
- 泛型下限:? super 类名 — 传递的要么是该类本身要么是该类的父类
public class FXDemo5 {
public static void main(String[] args) {
method(new Demo2<Number>());
method(new Demo2<Integer>());
method2(new Demo2<B>());
method2(new Demo2<A>());
}
public static void method(Demo2<? extends Number> d){
// d.setField(100);
System.out.println(d.getField());
}
public static void method2 (Demo2<? super B> d){
d.setField(new B());
System.out.println(d.getField());
}
}
class A {}
class B extends A{}