一、总结
1.泛型: 使用通配符来表示具体的类型。
2.泛型中的T表示的是类,而不能是基本数据类型,如int.
3.泛型做参数时,使用"类<?>",?是统配符,来接收此泛型的所有实例化对象或泛型的子类/接口实例化的对象。其它普通类的对象不能赋值。
4.报错的信息中CAP#1是一个泛型
5.Person<?>应该表示一个实例化过的泛型对象
public static void printInfo(Person<?> p)
6.在方法里面也可以使用泛型,参数为T,但是需要在函数签名前加<T>表示T是泛型而不是一个具体的类,eg:
public static <T> void printInfo2(Person<T> p) { }
7.子类继承也可以继续使用泛型或不使用
8.接口也可以使用泛型,可以认为接口就是一种特殊的父类
9.受限泛型
在定义一个泛型的时候指定其上限和下限。指定上限就是泛型T只能是某个类或其子类,指定下限就是泛型T只能是某个类或者是其父类。定义泛型时使用extends来指定上限,使用super来指定下限。
eg:指定上限,要求这些类都是来源于Number类或Number类的子类
class Student<T extends Number> implements Persion<T> { }
eg:指定下限,要求实例化对象都是String类或String类的父类。它是在成员方法中指定的
// 只能接收实例化为String或Object类型的对象(String类的父类只有Object类) public static void printinfo(Persion<? super String> p) { }
函数接收参数时:
使用 "<?>" 可以接收任意泛型对象。泛型的上限:<? extends 类型> 泛型的下限:<? super 类型>
10.Class<T>与Class<?>的区别
Class类的实例表示Java应用运行时的类或接口(每个Java类运行时都在JVM里表现为一个Class对象,可通过类名.class,类型.getClass()
Class.forName("类名")等方法获取Class对象)。
数组同样也被映射为为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。
基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为Class对象。
T bean;
Class<T> bean;
Class<?> bean;
单独的T代表一个类型,而Class<T>和Class<?>代表这个类型所对应的类
Class<T>在实例化的时候,T要替换成具体类
Class<?>它是个通配泛型,?可以代表任何类型
<? extends T>受限统配,表示T的一个未知子类。
<? super T>下限统配,表示T的一个未知父类。
Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,
类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。getClass()会看到返回Class<?>。
JDK中,普通的Class.newInstance()方法的定义返回Object,需要要将该返回类型强制转换为另一种类型;
二、试验例子
1.泛型实例化使用
interface Person<T> { public void setAge(T age); public T getAge(); } class Student<T> implements Person<T> { T age; public void setAge(T age) { this.age = age; } public T getAge() { return this.age; } } class Student2 implements Person<String> { String age; public void setAge(String age) { this.age = age; } public String getAge() { return this.age; } } public class Generics5 { public static void main(String args[]) { Student<Integer> s = new Student<Integer>(); s.setAge(10); printInfo(s); Student2 s2 = new Student2(); s2.setAge("11 years"); //also ok printInfo(s2); printInfo2(s2); } public static void printInfo(Person<?> p) { System.out.println(p.getAge()); } public static <T> void printInfo2(Person<T> p) { System.out.println(p.getAge()); } } /* $ java Generics5 10 11 years 11 years */
2.上限泛型
interface Person<T> { public void setAge(T age); public T getAge(); } /* Integer, Float */ class Student<T extends Number> implements Person<T> { /*指定上限*/ T age; public void setAge(T age) { this.age = age; } public T getAge() { return this.age; } } class Student2 implements Person<String> { String age; public void setAge(String age) { this.age = age; } public String getAge() { return this.age; } } public class Generics6 { public static void main(String args[]) { Student<Integer> s = new Student<Integer>(); s.setAge(10); printInfo(s); Student2 s2 = new Student2(); s2.setAge("11 years"); printInfo(s2); } public static void printInfo(Person<?> p) { System.out.println(p.getAge()); } public static <T> void printInfo2(Person<T> p) { System.out.println(p.getAge()); } }
3.下限泛型
interface Person<T> { public void setAge(T age); public T getAge(); } class Student<T> implements Person<T> { T age; public void setAge(T age) { this.age = age; } public T getAge() { return this.age; } } class Student2 implements Person<String> { String age; public void setAge(String age) { this.age = age; } public String getAge() { return this.age; } } public class Generics { public static void main(String args[]) { Student<String> s = new Student<String>(); s.setAge("10"); printInfo(s); Student2 s2 = new Student2(); s2.setAge("11 years"); printInfo(s2); } public static void printInfo(Person<? super String> p) { /*指定下限*/ System.out.println(p.getAge()); } public static <T> void printInfo2(Person<T> p) { System.out.println(p.getAge()); } }
本文参考链接:https://www.cnblogs.com/hellokitty2/p/10428347.html