网站建设优化推广,平面设计公司广告语,100款免费软件网站大全,西蔵自治区建设厅网站目录 一.什么是泛型
二.Java中为什么要使用泛型
三.泛型的语法
四.泛型类的使用
五.泛型的编译机制#xff08;擦除机制#xff09;
六.泛型的上界 一.什么是泛型
泛型#xff08;Generics#xff09;是Java SE 5中引入的一个新特性#xff0c;可以使Java中的类和方… 目录 一.什么是泛型
二.Java中为什么要使用泛型
三.泛型的语法
四.泛型类的使用
五.泛型的编译机制擦除机制
六.泛型的上界 一.什么是泛型
泛型Generics是Java SE 5中引入的一个新特性可以使Java中的类和方法具有更广泛的类型范围。通俗的说它使得我们可以在定义类和方法时指定一个或多个类型参数从而可以在不考虑具体类型的情况下代码中直接使用这些类型参数。泛型可以增强代码的安全性、可读性和可重用性。例如可以使用泛型实现容器类如ArrayList、HashMap等。在使用泛型时需要在编写代码时指定泛型类型这样可以在编译期间检查代码的类型安全性。
二.Java中为什么要使用泛型 一般的类和方法只能使用具体的类型:要么是基本类型要么是自定义的类。如果要编写可以应用于多种类型的代码这种刻板的限制对代码的束缚就会很大。 ----- 来源《Java编程思想》对泛型的介绍 Java中的泛型是一种允许在编写代码时指定类型参数的能力。使用泛型可以使代码更加通用且类型安全。通过使用泛型程序员可以编写一个方法或类该方法或类在实例化时可以接受不同类型的参数。泛型是将数据类型参数化进行传递这样可以减少代码的重复并提高代码的可读性和可维护性。
假如我们要实现一个数组使得其中能够存放任意数据类型的元素想存放整形又想存放字符型又想存放引用型该怎么办呢我们可以联想一下之前认识过的Object类Object类是所有类的父类那我们将数组置为Object类可以吗
class MyArray {public Object[] array new Object[10];public Object getPos(int pos) {return this.array[pos];}public void setVal(int pos,Object val) {this.array[pos] val;}
}public static void main(String[] args) {MyArray myArray new MyArray();myArray.setVal(0, 10);//整形可以存放myArray.setVal(1, hello);//字符串也可以存放String ret myArray.getPos(1);//编译报错原因是因为我们数组的类型是Object类型//但是我们这里接收的元素却是String类型//也就是说我们相当于进行了向下转型所以这里会报错//如果我们进行强制转化就可以解决这个问题//String ret (String) myArray.getPos(1);System.out.println(ret);} 我们会发现在这种情况下整体的语法其实是不灵活的虽然当前数组任何数据都可以存放但是更多情况下我们还是希望他只能够持有一种数据类型而不是同时持有这么多类型。 所以泛型的主要目的就是指定当前的容器要持有什么类型的对象让编译器去做检查。此时就需要把类型作为参数传递需要什么类型就传入什么类型。 三.泛型的语法
在充分认识了泛型的必要性和作用后我们来看看如何使用它在Java中泛型的使用方式是通过在类名或方法名后面加上尖括号然后在尖括号里指定类型参数。具体语法如下
class 泛型类名称类型形参列表 {// 这里可以使用类型参数
}
class ClassNameT1, T2, ..., Tn {
}
class 泛型类名称类型形参列表 extends 继承类/* 这里可以使用类型参数 */ {// 这里可以使用类型参数
}
class ClassNameT1, T2, ..., Tn extends ParentClassT1 {// 可以只使用部分类型参数
}
可以通过泛型实例化一个泛型对象
泛型类类型实参 变量名; // 定义一个泛型类引用
new 泛型类类型实参(构造方法实参); // 实例化一个泛型类对象MyArrayInteger list new MyArrayInteger();
当编译器可以根据上下文推导出类型实参时可以省略类型实参的填写
MyArrayInteger list new MyArray(); // 可以推导出实例化需要的类型实参为 Integer
泛型只能接受类所有的基本数据类型必须使用包装类
四.泛型类的使用
对于我们刚才的数组我们就可以如下设置为一个泛型数组
class MyArrayT {public T[] array (T[])new Object[10];//1//public T[] array;public T getPos(int pos) {return this.array[pos];}public void setVal(int pos,T val) {this.array[pos] val;}
} public static void main(String[] args) {MyArrayInteger myArray1 new MyArray();//2myArray1.setVal(0,10);myArray1.setVal(1,12);MyArrayString myArray2 new MyArray();//3myArray2.setVal(0,hello);myArray2.setVal(1,world);MyArrayFloat myArray3 new MyArray();//4myArray3.setVal(0,1.23f);myArray3.setVal(1,3.14f);}
在上述代码块中
类名后的 T 代表占位符表示当前类是一个泛型类常用的其他名称有
E 表示 ElementK 表示 KeyV 表示 ValueN 表示 NumberT 表示 TypeS, U, V 等等... ...
注释1处不能new泛型类型的数组也就是说下面这样的代码是错误的
T[] arrary new T[5];//是不对的
注释2处类型后加入 Integer 指定当前类型注释34处同理
五.泛型的编译机制擦除机制
Java的类型擦除机制是指在编译期间将泛型的类型参数替换为其边界或Object类型从而实现泛型代码运行时无需知晓实际类型参数也就是说泛型的类型参数在运行时是被擦除了的。这个机制是为了兼容Java语言的旧版本同时也可以减少代码重复使得代码更加简洁。
举个例子来说 假如有一个泛型类ListT其中的T可以指定任何类型但是在运行时ListT的实际类型是ListObject。那么当我们在使用ListT时编译器会自动擦除类型参数T然后将ListT替换为ListObject这样就可以在运行时使用Object类型来处理元素。 在编译期间泛型类型参数String被擦除了ListString被替换成了ListObject而在运行时get方法返回的是Object类型需要强制转换为String类型也就是说我们无法在运行时获取到类型参数的具体值因为编译器已经将其擦除了。 泛型到底是如何进行编译的这曾经作为面试题进行考察过泛型的语法实际上是非常复杂不容易理解的我们需要借助他的字节码文件去观察使用命令javap -c 查看字节码文件 也就是说在编译的过程当中将所有的T替换为Object这种机制我们称为擦除机制 这个类型擦除机制也给开发带来了一些限制和挑战比如不能在运行时获取泛型参数的具体类型泛型数组的创建受到限制等。但是通过一些技巧和设计模式我们可以在一定程度上绕过这些限制让代码更加灵活和可扩展。 六.泛型的上界
在定义泛型类时有时需要对传入的类型变量做一定的约束可以通过类型边界来约束语法
class 泛型类名称类型形参 extends 类型边界 {//... ...
}
例如
public class MyClassT extends MyClass2 {// ...
}上述代码中泛型类型T的上界是MyClass2这意味着在使用MyClass时只能传入MyClass2或其子类作为T的实际类型参数。这样做可以确保在类型安全的前提下使用泛型类型时具有更大的灵活性和可扩展性。
假设我们有一个泛型类BoxT我们希望确保这个类型参数T必须是实现了Comparable接口的类。我们可以使用泛型的上界T extends ComparableT来实现这个目标示例代码如下
public class BoxT extends ComparableT {private T value;public Box(T value) {this.value value;}public T getValue() {return value;}public boolean isGreaterThan(BoxT otherBox) {return value.compareTo(otherBox.getValue()) 0;}
}在这个示例中我们使用T extends ComparableT来定义类型参数上界确保T必须是实现了Comparable接口的类。这样我们就可以在isGreaterThan()方法中使用value.compareTo()方法来比较value字段和另一个Box对象的值了。 本次的分享就到此为止了希望我的分享能给您带来帮助也欢迎大家三连支持你们的点赞就是博主更新最大的动力如有不同意见欢迎评论区积极讨论交流让我们一起学习进步有相关问题也可以私信博主评论区和私信都会认真查看的我们下次再见