江苏建设行业证书编号查询网站,为什么网站搜索不到,文档生成器app,无障碍网站建设推广前景12 泛型
12.1 为什么使用泛型
泛型程序设计#xff08;Generic programming#xff09;#xff1a;意味着编写的代码可以被很多不同类型的对象所重用。
类型参数#xff08;type parameters#xff09;
通配符类型#xff08;wildcard type#xff09; 可以将Manage…12 泛型
12.1 为什么使用泛型
泛型程序设计Generic programming意味着编写的代码可以被很多不同类型的对象所重用。
类型参数type parameters
通配符类型wildcard type 可以将Manager添加到ArrayListEmployee中但不能把Employee添加到ArrayListManager中。 12.2 定义简单泛型类
一个泛型类Generic class就是具有一个或多个类型变量的类。
public class PairT, U{...}
类型变量用大写形式且比较短。 在Java库中E表示集合的元素类型K和V分别表示关键字和值的类型T、U、S表示任意类型。 泛型类可看做普通类的工厂。 12.3 泛型方法
可以定义一个带有类型参数的简单方法这个方法可以在普通类中也可以在泛型类中。
类型变量T放在修饰符和返回类型之间。
当调用泛型方法时在方法名前的尖括号中放入具体的类型。
也可以不放具体类型编译器会进行类型推断。 class ArrayAlg
{public static T T getMiddle(T ... a){return a[a.length / 2];}
}String middle ArrayAlg.StringgetMiddle( “John”, “Q”, “Public”);
String middle ArrayAlg.getMiddle( “John”, “Q”, “Public”);12.4 类型变量的限定
public static T extends Comparable T min(T[] a) { ... }
public static T extends Comparable Serializable T min(T[] a) { ... } 限定中至多有一个类且必须放在限定列表中的首位。 12.5 泛型代码和虚拟机
虚拟机没有泛型类型对象--所有对象都属于普通类。
定义一个泛型类型时都自动提供了一个相应的原始类型raw type。
原始类型的名字就是删去类型参数后的泛型类型名。
擦除erased类型变量替换为限定类型无限定类型用Object。
泛型方法同上。 这是与C模板最大的区别C每个模板的实例化产生不同的类型这一现象称为“模板代码膨胀”。 小结
·虚拟机中没有泛型只有普通的类和方法
·所有的类型参数都用它们的限定类型替换
·桥方法被合成来保持多态
·为保持类型安全性必要时插入强制类型转换。 桥方法位于声明类型的泛型类中
public void setSecond(Object second) { setSecond((Data) second)};
public Data getSecond{ return (Date) super.getSecond().clone();} 12.6 约束与局限性
1、不能用基本类型实例化类型参数 2、运行时类型查询只适用于原始类型。
虚拟机中的对象总有一个特定的非泛型类型因此所有的类型查询只产生原始类型。
if (a instanceof PairString) //ERROR
if (a instanceof PairT) //ERROR
PairString p (PairString) a; //WARNING--can only test that a is a Pair.
无论何时使用instanceof或涉及泛型类型的强制类型转换表达式都会看到一个编译器警告。 同理getClass方法总是返回原始类型。
PairString stringPair ...;
PairEmloyee employeePair ... ;
if (stringPair.getClass() employeePair.getClass()) //they are equal
//两次调用getClass都将返回Pair.class 3、不能实例化参数化类型数组
PairString[] table new PairString[10]; // ERROR
ArrayListPairString table new ArrayListPairString(); //RIGHT 4、向参数个数可变的方法传递一个泛型类型的实例
public static T void addAll( CollectionT coll, T ... ts)
实际上ts是一个数组这违反了3但此时规则有些放松只会得到警告。
可用SafeVarargs来消除警告。
或者SuppressWarnings(“unchecked”)来抑制警告 5、不能实例化类型变量
不能使用new T(...); new T[...]; T.class
可以这样用 public static T PairT makePair(ClassT c1)
{try { return new Pair( c1.newInstance(), c1.newInstance())}catch (Exception ex) { return null;}
}Class类本身就是泛型String.class是一个ClassString的实例。 6、禁止使用带有类型变量的静态域和方法 7、不能抛出或捕获泛型类的实例 12.7 泛型类型的继承规则
无论S与T有什么关系PairS PairT都没什么关系。
泛型类可以扩展或实现其他的泛型类。这一点与普通的类没有什么区别。 12.8 通配符类型
? 通配符。也可以理解为占位符。
? extends E: 可以接收E类型或者E的子类型。上限
? super E: 可以接收E类型或者E的父类型。下限 用的比较少见集合的比较器 Pair? extends Employee 子类型限定
Pair? super Manager 超类型限定 PairManager是Pair? extends Employee的子类型
PairEmploy是Pair? super Manager的子类型 12.9 反射和泛型
Class类是泛型的。
使用反射API可以确定
·类型参数T
·子类型限定
·通配符参数
·超类型限定
·参数为泛型