看到Optional的源代码看到这样一段很意外,竟然出现了泛型对象转型。因为static属性是类加载初始化,获取不到泛型参数的,所以只能是声明Optional<T>,而不是Optional<?>.
private static final Optional<?> EMPTY = new Optional<>(); public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; }
首先泛型不能直接强转。比如下面的代码是编译不通过的。
但是我们通过无界通配做中间人试一试竟然是可以的。这个就让我感觉自己孤陋寡闻了。
List<Integer> listI=new LinkedList<>(); List<String>listS=new LinkedList<>(); List<?> list=new LinkedList<>(); list=listI; listS=(List<String>)list;
但是很显然这样会有问题啊,integer是无法转型成string的
那我们试一下可以转型的试试。比如Integer 和Long,就没有任何问题哈。
这里面有一个疑问,意味着在java里面可以通过Long类型来操作Integer类型对象哦。这意味着类型和值是分离的哦。了解动态绑定的应该知道,java可以在运行时找到实际类型的对应方法。说白了就是能够在内存里面找到正确的方法的位置。
增加一个测试代码
package com.example.demo;
public class Test{
public static void main(String[] args) {
Apple apple = new Apple("苹果");
RedApple redApple=new RedApple("红苹果","red");
Container<Apple> c1=new Container(apple);
Container<RedApple> c2=new Container(redApple);
Container<?> c3=c1;
// c1=c2;
c3=c2;
c1=(Container<Apple>)c3;
System.out.print(c1.entity.name);
}
static class Container<T> {
private T entity;
public Container(T t) {
this.entity = t;
}
}
static class Apple {
public Apple(String name) {
this.name = name;
}
String name;
}
static class RedApple extends Apple {
public RedApple(String name, String color) {
super(name);
this.color = color;
}
String color;
}
}