Java基础之:自定义泛型
自定义泛型的细节:
-
普通成员可以使用泛型(属性与方法)
-
使用泛型的数组不可初始化
-
静态方法中不可使用类的泛型
-
泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)
-
如果在创建对象时,没有指定类型,默认为Object
package class_Generic_custom; public class ClassTest01_customGeneric { public static void main(String[] args) { //可以在自定义类或接口中使用泛型 AA<String> a = new AA<>("hi"); a.say();//String //这里使用Integer,而不是int。因为泛型接收传入的类型只能是引用类型。 AA<Integer> b = new AA<>(123); b.say();//Integer } } class AA<T>{ //泛型一般使用T来表示,type。 private T t; //创建T类型的属性 t public void say() { System.out.println(t.getClass()); //返回t的类型 } public AA(T t) { this.t = t; } } class BB<E,T>{ //泛型可以有多个 E e; T t; // public static E es;//泛型不可以使用static修饰,因为泛型是在创建对象是传入的。 //使用泛型的数组,不能初始化 E[] eArr /*= new E[6]*/; //报错:Cannot create a generic array of E public void seteArr(E[] arr) { //使用set方法传入参数来定义泛型数组,或构造器 eArr = arr; } //静态方法中不能使用类的泛型 // public static void show(E e) { //报错:Cannot make a static reference to the non-static type E //静态方法使用时,可能并没有创建对象,那么e的类型也无法确定 // } }
自定义泛型接口
-
接口中,静态成员也不能使用泛型(这个和泛型类规定一样)
-
泛型接口的类型, 在接口被扩展时(即:被继承或者实现) 会确定 [后面举例]
-
没有指定类型,默认为Object [后面举例]
package class_Generic_custom; public class ClassTest04_GenericInterface { public static void main(String[] args) { } } //自定义泛型接口 interface IA<T>{ public T show(); //返回T类型的数据 } //若有类实现了泛型接口,那么在继承的时候 就需要指定泛型。 class IIAA implements IA<String>{ @Override public String show() { return "IIAA"; } } //若有类实现了泛型接口,但此类本身也时泛型类,可以在创建类时不指定接口的泛型。 //将类的泛型传递给接口。 class BBB<E> implements IA<E>{ @Override public E show() { return null; } } class CC<K>{ } //若既继承了泛型父类,又实现了泛型接口,可以分别为它们传递泛型 //也可以像上面一样使用一个泛型,传递给它们。 class DD<E,T,V> extends CC<E> implements IA<T>{ @Override public T show() { return null; } }
自定义泛型方法
1) 泛型方法,可以定义在普通类中, 也可以定义在泛型类中
2) 当泛型方法被调用时,类型会确定.
package class_Generic_custom; public class ClassTest03_GenericMethods { public static void main(String[] args) { MM<String> m = new MM<>(); m.show(123);//Integer m.say(new Object());//Object } } class MM<T>{ //自定义泛型方法 public<E> void show(E e) { System.out.println(e.getClass());//返回E,即E是什么类型传入,那么输出就是什么类型 } //当泛型类与自定义泛型方法使用的泛型重名时,采用就近原则 public<T> void say(T t) { System.out.println(t.getClass()); } }
泛型的继承和通配符
说明
1.泛型不具有继承性,例如:
List<Object> list = new ArrayList<String>(); //×
2.<?>:表示支持任意泛型类型
3.<? extends A>:表示支持A类以及A类的子类,规定了泛型的上限
4.<? super A>:表示支持支持A类以及A类的父类,不限于直接父类,规定了泛型的下限。
package class_Generic_custom; import java.util.ArrayList; public class ClassTest02_ExtendsGeneric { public static void main(String[] args) { // 泛型不具备继承性 // ArrayList<Object> list = new ArrayList<String>(); ArrayList<Object> list1 = new ArrayList<>(); ArrayList<String> list2 = new ArrayList<>(); ArrayList<Grandpa> list3 = new ArrayList<>(); ArrayList<Father> list4 = new ArrayList<>(); ArrayList<Son> list5 = new ArrayList<>(); // print(list1);//X //Object 不属于 Father及其子类 // print(list2);//X //String 不属于 Father及其子类 // print(list3);//X //Grandpa 属于 Father 父类 // print(list4);//√ // print(list5);//√ // print2(list1);//√ // print2(list2);//X //String 不属于 Father及其父类 // print2(list3);//√ // print2(list4);//√ // print2(list5);//X //Son 属于 Father子类 // print3(list1);//√ // print3(list2);//√ // print3(list3);//√ // print3(list4);//√ // print3(list5);//√ } public static void print(ArrayList<? extends Father> e) { } public static void print2(ArrayList<? super Father> e) { } public static void print3(ArrayList<?> e) { } } class Grandpa{ public void hi() { System.out.println("hi~"); } } class Father extends Grandpa{ public void hello() { System.out.println("hello~"); } } class Son extends Father{ public void show() { System.out.println("show~"); } }