泛型概述
- JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
- 泛型的格式<数据类型>,数据类型只支持引用数据类型
- 集合体系的所有接口和实现类都支持接口
泛型的作用
- 声明集合元素的类型
- 限制加入集合元素的类型
//代码段1
public static void main(String[] args) {
List<String> list;
list = new ArrayList();
list.add("这是一个字符串");
//list.add(5);//提示:不兼容的类型: int无法转换为java.lang.String
System.out.println(list.get(0).length());//7
}
IDEA执行上述代码可以发现当我们定义一个String泛型的List时,无法加入数字类型的元素。起到了限制加入元素数据类型的作用。
下面是不使用泛型的List定义方式
//代码段2
public static void main(String[] args) {
List list;
list = new ArrayList();
list.add("这是一个字符串");
list.add(5);
System.out.println(((String)list.get(0)).length());//7
}
查看上述代码可以发现,输出list长度时的写法要复杂的多,因为我们获取list.get(0)时,系统并不知道它是什么类型的数据,所以要用String先对get(0)的结果进行强制类型转换。
java7加强的<>(菱形)
在java7以前,如果定义一个String泛型的list则必须这样写
List<String> list = new ArrayList<String>();
在这段代码里我们可以看到后面的String类型有些多余,从java7开始,就可以将上述代码简化为
List<String> list = new ArrayList<>();
把两个尖括号放在一起看起来像一个菱形,因此,这种写法也叫菱形语法
通过菱形语法修改代码段1后为
public static void main(String[] args) {
List<String> list;
list = new ArrayList<>();
list.add("这是一个字符串");
//list.add(5);//提示:不兼容的类型: int无法转换为java.lang.String
System.out.println(list.get(0).length());//7
}
有的小伙伴会疑惑,说好的简化,为什么还多了一对<>呢?
这是因为代码段1和代码段2不符合java语法规范,虽然在IDEA里可以正常运行,但在编译时往往会遇到问题,检查出“***.java使用了未经检查或不安全的操作”的注意事项,使用-Xlint:unchecked才能成功编译。因此,保持一个良好的编码习惯可以再开发中规避许多问题。
var
当使用var定义变量时,因为编译器无法推断变量的类型,所以不能使用菱形语法。定义格式需修改为如下格式:
var list = new ArrayList<String>();
Java9再次增强的菱形语法
java9开始,它允许在创建匿名内部类时使用菱形语法,java可根据上下文推断匿名内部类中泛型的类型。下面是演示代码:
public interface Foo<T> {
void test(T t);
}
public class AnonymousTest{
public static void main(String[] args) {
Foo<String> f1 = new Foo<>() {
@Override
public void test(String s) {
System.out.println("输出String:"+s);
}
};
Foo<Integer> f2 = new Foo<>() {
@Override
public void test(Integer i) {
System.out.println("输出Integer:"+i);
}
};
}
}
内部方法的泛型和实例化时使用的泛型需要保持一致,如果不一致,系统将会报错