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~");
}
}
