Java 泛型的参数只可以代表类,不能代表个别对象。由于 Java 泛型的类型参数之实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而 加快。Java 允许对个别泛型的类型参数进行约束,包括以下两种形式(假设 T 是泛型的类型参数,C 是一般类、泛类,或是泛型的类型参数):T 实现接口 I 。T 是 C ,或继承自 C 。一个泛型类不能实现Throwable接口。
成都创新互联是一家集网站建设,巴青企业网站建设,巴青品牌网站建设,网站定制,巴青网站建设报价,网络营销,网络优化,巴青网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
对泛型类 User< T, K > 而言,声明了两个泛型类参数:T 和 K。在类中试图根据类型参数的不同重载 set() 方法。这看起来没什么问题,可编译器会报错
public class User {
//重载错误
public void set(T t) {
}
//重载错误
public void set(K k) {
}
}
首先,当声明 User 对象时,T 和 K 实际上不需要一定是不同的类型,以下的两种写法都是正确的
public class GenericMain {
public static void main(String[] args) {
User stringIntegerUser = new User<>();
User stringStringUser = new User<>();
}
}
对于第二种情况,T 和 K 都将被 String 替换,这使得 set() 方法的两个版本完全相同,所以会导致重载失败。
此外,对 set() 方法的类型擦除会使两个版本都变为如下形式:
一样会导致重载失败
public void set(Object o) {
}
不能创建类型参数的实例。因为编译器不知道创建哪种类型的对象,T 只是一个占位符
public class User {
private T t;
public User() {
//错误
t = new T();
}
}
静态成员不能使用在类中声明的类型参数,但是可以声明静态的泛型方法
public class User {
//错误
private static T t;
//错误
public static T getT() {
return t;
}
//正确
public static void test(K k) {
}
}
不能实例化元素类型为类型参数的数组,但是可以将数组指向类型兼容的数组的引用
public class User {
private T[] values;
public User(T[] values) {
//错误,不能实例化元素类型为类型参数的数组
this.values = new T[5];
//正确,可以将values 指向类型兼容的数组的引用
this.values = values;
}
}
此外,不能创建特定类型的泛型引用数组,但使用通配符的话可以创建指向泛型类型的引用的数组
public class User {
private T[] values;
public User(T[] values) {
this.values = values;
}
}
public class GenericMain {
public static void main(String[] args) {
//错误,不能创建特定类型的泛型引用数组
User[] stringUsers = new User<>[10];
//正确,使用通配符的话,可以创建指向泛型类型的引用的数组
User>[] users = new User>[10];
}
}
泛型类不能扩展 Throwable,意味着不能创建泛型异常类