“参数化类型”,平时定义任何方法时,例如传入int x,y属于典型的形参,调用时传入的1、2就是实参,参数类型在定义的时候参数类型本身参数化,在实际调用时告诉我们传入什么类型的参数
public class ImplGenertor implements Genertor {
@Override
public T next() {
return null;
}
}
public class ImplGenertor2 implements Genertor {
@Override
public String next() {
return null;
}
}
public class Generic {
private T key;
public Generic(T key) {
this.key = key;
}
/* ---------------- 1 ---------------- */
// 虽然在方法中使用了泛型,但并不是一个泛型方法
// 这只是类中一个普通的成员方法,只不过返回值是在声明泛型类已经声明过的泛型
// 所以在这个方法中才可以继续使用T这个泛型
public T getKey() {
return key;
}
/* ---------------- 2 ---------------- */
// 使用了Generic这个泛型类做形参的普通方法。
public void show(Generic num) {
}
}
/** 首先在方法权限关键字与返回值之间的必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
* 这个T可以出现在这个泛型方法的任意位置.
* 泛型的数量也可以为任意多个
* 如:public K showKeyName(Generic container){
* ...
* }
*/
public static T min(T a,T b){
if(a.compareTo(b) > 0) {
return a;
} else {
return b;
}
}
/* 为了确保传入的两个变量一定有compareTo方法,解决方案为将T限制为实现了接口Comparable的类 */
public static T min(T a, T b){
if(a.compareTo(b) > 0) {
return a;
} else {
return b;
}
}
/* 限定类型可以多个,类和接口均行,若类和接口混用,类必须放在第一位,且只能有一个(原因Java是单继承多实现) */
public static T min(T a, T b){
if(a.compareTo(b) > 0) {
return a;
} else {
return b;
}
}
public Restrict() {
this.data = new T();
}
private static T instance;
注:静态方法是泛型方法就没有问题
private static T instance(){}
// if(restrict instanceof Restrict)
// if(restrict instanceof Restrict)
Restrict restrict = new Restrict<>();
Restrict restrictString = new Restrict<>();
System.out.println(restrict.getClass() == restrictString.getClass());
System.out.println(restrict.getClass().getName());
System.out.println(restrictString.getClass().getName());
// Resulet
true
*.Restrict
*.Restrict
// 允许声明数组
Restrict[] restrictArray;
// 不允许
// Restrict[] restricts = new Restrict[10];
// private class Problem extends Exception;
// public void doWork(T t) {
// try {
//
// } catch (T e) {
// // do something
// }
// }
/* 注:虽然不能捕获它,但可以抛出写到throws子句里 */
public void doWork(T t) throws T {
try {
} catch (Throwable throwable) {
throw t;
}
}
private static void set(Pair p){
}
public static void main(String[] args) {
Pair employeePair = new Pair<>();
Pair workerPair = new Pair<>();
Employee employee = new Worker();
// Pair和Pair没有任何继承关系
// Pair employeePair2 = new Pair();
Pair pair = new ExtendPair<>();
set(employeePair);
// set(workerPair);
}
/*泛型类可以继承或者扩展其他泛型类,比如List和ArrayList*/
private static class ExtendPair extends Pair{
}
public static void print(GenericType p) {
System.out.println(p.getData().getColor());
}
public static void use() {
GenericType a = new GenericType<>();
print(a);
GenericType b = new GenericType<>();
//print(b); 方法print不允许传入对象b
}
/* --------------------------- 通配符的引入 --------------------------- */
public static void print2(GenericType extends Fruit> p) {
System.out.println(p.getData().getColor());
}
public static void use2() {
GenericType a = new GenericType<>();
print2(a);
GenericType b = new GenericType<>();
print2(b);
/** 注:? extends X代表类型的上界,类型参数是X或X的子类 */
//print2(new GenericType());
// 对象c可赋值于a或b,GenericType extends Fruit> c = a/b;
GenericType extends Fruit> c = new GenericType<>();
/* ? extends X 主要用于安全访问数据 */
Apple apple = new Apple();
Fruit fruit = new Fruit();
// 编译器不知道传入是类Fruit或类Fruit的子类
//c.setData(apple);
//c.setData(fruit);
// 调用方法getData()获得的是Fruit类型
//Apple x = c.getData();
//Orange x = c.getData();
Fruit x = c.getData();
}
/** ? super X 表示类型的下界,类型参数是X或X的超类,主要用于安全写入数据 */
public static void printSuper(GenericType super Apple> p){
System.out.println(p.getData());
}
public static void useSuper(){
GenericType fruitGenericType = new GenericType<>();
GenericType appleGenericType = new GenericType<>();
GenericType redFujiGenericType = new GenericType<>();
GenericType orangeGenericType = new GenericType<>();
printSuper(fruitGenericType);
printSuper(appleGenericType);
//printSuper(redFujiGenericType); // 类Apple的子类,故报错
//printSuper(orangeGenericType); // 平级类,跟类Apple没关系
// 表示GenericType的类型参数的下界是Apple
GenericType super Apple> x = new GenericType<>();
// 方法setData()编译器不知道传入的确切类型,但传入类Apple或类Apple的子类能安全转型为对象Apple
x.setData(new Apple());
x.setData(new HongFuShi());
//x.setData(new Fruit());
// 返回一定是Apple的超类,具体哪个超类不知道,唯一确定是类Object是类Apple的超类
Object data = x.getData();
}
public class GenericRaw {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static void main(String[] args) {
}
}
在JDK里类型擦除可理解为擦除成Object
public class GenericRaw
学习笔记,如有错漏,理解不到位,烦请多多提点,拜谢!
若需转载,声明出处即可
简书 && github