少见的类型推断
public static <T> T getBean(String key) {
T ret = null;
try {
Class<?> clz = Class.forName(key);
ret = (T) clz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
public static <K, V> Map<K, V> map() {
return new HashMap<>();
}
- getBean() 和 map() 方法都使用了类型参数推断。
- 当作为方法参数传递时,编译器不会执行类型推断,而会被认为返回值被赋值给Object类型的变量(java编程思想P363),故IDE不会报错,但运行时会报ClassCastException;
编译器加入
当我们执行这段代码时,类型参数推断已经帮我们进行转型了。查看编译后的class文件,里面内容实际还是进行了转型(也就是类型推断是编译器做的事)
UserService userService = BeanFactory.getBean("userService");
// 变为class后:
UserService userService = (UserService)BeanFactory.getBean("userService");
钻石表达式经过编译:
Map<String, Object> map = new HashMap<>();
// 变为class后:
Map<String, Object> map = new HashMap();
显式地指明类型
- 使用this.尖括号+方法名 或 类名.尖括号+方法名
普通方法:this.<UserService, UserController>map();
静态方法:BeanFactory.<UserService, UserController>map();
BeanFactory.f(BeanFactory.<UserService, UserController>map());