今天实在是太累了,休息了一会,继续写博客。今天还是继续研究泛型的问题,通过这两天写博客的经历,发现这既是一个很困难的过程,也是非常有收获的一种学习方法。废话不多说,直接上代码:
class Holder<T>
{
private T value;
public Holder() {}
public Holder(T val){ value = val;}
public void set(T arg){ value = arg;}
public T get(){return value;}
public boolean equals(Object obj)
{
return value.equals(obj);
//Object的.equals方法是判断对象是否相同,而不是值
}
}
public class CaptureConversion
{
static <T> void f1(Holder<T> holder)
//f1方法中都是确切的类型参数,没有通配符或者边界
{
T t = holder.get();
System.out.println(t.getClass().getSimpleName());
}
static void f2(Holder<?> holder)
/* f2方法中是将无界通配符作为参数,在f2方法中参数类型被捕获,然后被发送给f1方法,
* 但是在f2整个方法中T参数都是未知的*/
{
f1(holder);
}
@SuppressWarnings("rawtypes")
public static void main(String[] args)
{
Holder raw = new Holder<Integer>(1);
//f1(raw);
/* 警告:1.类型转换捕获,f1方法需要一个带有类型参数的Holder但是提供的是一个原型
* 2.泛型转换异常,Holder被当作Holder<Object>进行使用*/
f2(raw);
Holder rawBasic = new Holder();
rawBasic.set(new Object());
/* 警告:set方法是需要一个类型参数的方法
* 解决这个问题不能通过添加<?>或者<? extends Object>解决
* 而是只能通过添加<? super Object>进行解决*/
f2(rawBasic);
Holder<?> wildcarded = new Holder<Double>(1.0);
f2(wildcarded);
}
}
总结一下捕获转换的使用要点就是:当一个容器由一个特定的类型参数转换为原型或者是通配符’?’时,可以通过先用一个使用’?’的方法保存容器,再将容器作为参数传递给泛型方法。例如上面代码中f2调用了f1,这样就可以在泛型方法中使用确切的参数类型。