一、标识符和关键字的区别是什么?
在我们编写程序的时候,需要大量地为程序、类、变量、方法等取自定义名字,于是就有了标识符,简单来说,标识符就是一个名字。但是有一些标识符,Java 语言已经赋予了其特殊的含义,只能用于特定的地方,这种特殊的标识符就是关键字。因此,关键字是被赋予特殊含义的标识符。
二、泛型
1、什么是泛型
泛型是我们在写公共方法时,很实用的一个参数化类型。
在泛型没出现时,我们在写公共方法时, 比如Excel处理类ExcelUtil,为了实现参数的"任意化",我们会定义参数为Object类型,但这种方法的缺点是要做显示的强制类型转换,而这种转换是要开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这本身就是一个安全隐患。
Java 泛型(generics) 是 JDK 5 中引入的一个新特性, 它允许我们定义”任意化“的参数类型,比如ExcelUtil,使用时指定为一个具体的数据类型,这样程序在编译时,就能检测到非法的类型。
所以,使用泛型的好处就是在编译的时候能够检查类型安全,并且所有的强制转换都是自动和隐式的。
2、类型擦除
在编译的时候,泛型能够安全的检查类型,但在使用下面的方法调用时,却可以跨类型,java代码示例:
List<Integer> list = new ArrayList<>();
list.add(25);
//这里直接添加会报错
list.add("aa");
Class<? extends List> clazz = list.getClass();
Method add = clazz.getDeclaredMethod("add", Object.class);
//但是通过反射添加是可以的
//这就说明在运行期间所有的泛型信息都会被擦掉
add.invoke(list, "jin");
System.out.println(list);
所以,通过反射方法可以看出,Java 的泛型实际上是伪泛型。在 Java 运行期间,所有的泛型信息都会被擦掉,这也就是通常所说的类型擦除 。
3、常用的通配符
常用的通配符为: T,E,K,V,?
- T (type) 表示具体的一个 Java 类型
- E (element) 代表 Element
- K V (key value) 分别代表 Java 键值中的 Key Value
- ? 表示不确定的 Java 类型
本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T ,在可读性上可能会弱一些。
4、泛型的使用方式
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法。
1)泛型类
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T> {
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey() {
return key;
}
}
如何实例化泛型类:
Generic<Integer> genericInteger = new Generic<Integer>(123);
2)泛型接口
public interface Generator<T> {
public T method();
}
实现泛型接口,不指定类型:
class GeneratorImpl<T> implements Generator<T>{
@Override
public T method() {
return null;
}
}
实现泛型接口,指定类型:
class GeneratorImpl implements Generator<String>{
@Override
public String method() {
return "hello";
}
}
3)泛型方法
public static <E> void printArray(E[] inputArray) {
for (E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
使用:
// 创建不同类型数组: Integer, String
Integer[] intArray = { 1, 2, 3 };
String[] stringArray = { "Hello", "World" };
printArray(intArray);
printArray(stringArray);