泛型
概念
泛型是(Generics)是JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小手段,小技巧,虚拟机层面是不存在所谓『泛型』的概念的。
标志<> 。常用来约束集合中的元素类型。并且能把报错时机提前。
作用
- 通过泛型的语法定义,约束集合元素的类型,进行安全检查,把错误显示在编译期
- 代码通用性更强,后面有案例
- 泛型可以提升程序代码的可读性,但它只是一个语法糖(编译后这样的东西就被删除,不出现在最终的源代码中),对于JVM运行时的性能是没有任何影响的。
声明
泛型可以在接口、方法、返回值上使用:
//java.util.List泛型接口/类:
public interface Collection<E> {}
//泛型方法的声明:
public <E> void print(E e) {}
//在方法返回值前声明了一个<E>表示后面出现的E是泛型,而不是普通的java变量。
常用名称
-
E - Element (在集合中使用,因为集合中存放的是元素)
-
T - Type(Java 类)
-
K - Key(键)
-
V - Value(值)
-
N - Number(数值类型)
-
? - 表示不确定的java类型
测试案例:编译时检查错误
package cn.tedu.io;
import java.util.ArrayList;
import java.util.List;
public class Test3_Generic {
public static void main(String[] args) {
//3、不使用泛型约束的集合,可以添加任意类型元素
// List list = new ArrayList() ;
//5、泛型约束的元素类型 ,<what> -- what是指元素类型,而且写引用类型不能写基本类型!!
List<Integer> list = new ArrayList<>() ;//4、使用了泛型,约束了集合中元素类型必须是String
//1、限制集合中的元素类型? -- 泛型的作用1:可以检查数据的类型。如果类型对才可以向集合中添加。
//2、泛型的作用2:可以把报错的时机提前,如果有错编译都通不过,必须改。
//问题是:向集合中添加任意类型的数据,太自由!!
list.add(123);
// list.add("5.5");
// list.add("jack");
// list.add("rose");
System.out.println(list);
}
}
测试案例:通用性更强
使用泛型前
package cn.tedu.io;
//这个类用来测试 泛型的通用性
public class Test4_Generic {
public static void main(String[] args) {
Integer[] a = {1,2,3,4,5};
print(a) ;
Double[] b = {1.1,2.2,3.3,4.4,5.5};
print(b) ;
String[] c = {""};
// print(c) ;//1、问题是:又得提供重载的print()!!
}
public static void print(Double[] b) {
//foreach:
for(Double dou : b) {
System.out.println(dou);
}
}
public static void print(Integer[] a) {
// for (int i = 0; i < a.length; i++) { System.out.println(a[i]); }
//foreach语法:提高普通for循环的执行效率 + 语法简洁
//for( 获取到的数据类型 变量名 : 想要循环的数组名){ 循环体 }
for( Integer in : a ){
System.out.println(in);//in表示当前获取到的数据
}
}
}
使用泛型后
package cn.tedu.io;
//这个类用来测试 泛型的通用性
public class Test4_Generic {
public static void main(String[] args) {
Integer[] a = {1,2,3,4,5};
Double[] b = {1.1,2.2,3.3,4.4,5.5};
String[] c = {""};
print(a) ;
print(b) ;
print(c) ;//1、问题是:又得提供重载的print()!!
}
//2、以前参数列表,写死了,必须是具体类型。泛型写出通用代码,只要是E泛型类型就行。
public static <E> void print(E[] a) {
// for (int i = 0; i < a.length; i++) { System.out.println(a[i]); }
//foreach语法:提高普通for循环的执行效率 + 语法简洁
//for( 获取到的数据类型 变量名 : 想要循环的数组名){ 循环体 }
for( E in : a ){
System.out.println(in);//in表示当前获取到的数据
}
}
}