日期:2014-05-20  浏览次数:20736 次

java泛型 问题
额。。。java泛型的复杂性简直出人意表。中间种种错综复杂的转型和匹配关系简直要人命啊。。。刚写出了如下的出错代码,实在自己不想去翻关于泛型的资料了。。。还求各高手拔刀相助!!
出错 代码如下:
import java.util.*;
import java.lang.reflect.*;

public class Holder<T> {
private T value;
public Holder(){}
public Holder(T val){value = val;}
public void set(T val){value = val;}
public T get(){return value;}
public boolean equals(Object obj){
return obj.equals(value);
}
}

public class Chapter29 {
static void test(Holder<List<?>> holl){

}
public static void main(String[] args){
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(1));
List<Holder<Double>> lh = new ArrayList<Holder<Double>>();
lh.add(new Holder<Double>(0.1));
Holder<List<Integer>> hl1 = new Holder<List<Integer>>(li);
Holder<List<Holder<Double>>> hld= new Holder<List<Holder<Double>>>(lh);
test(hl1);//报错
test(hld);//报错
}
}
想请问各位,上面的代码,倒数三四行报错。为什么通用符在这里不能成功匹配?
而下面的代码却可以:
public class Wildcards {
static void unboundedArg(Holder<?> holder,Object arg){
Object obj = holder.get();
}
public static void main(String[] args){
Holder raw = new Holder();
Holder<Long> qualified = new Holder<Long>();
Holder<?> unbounded = new Holder<Long>();
Holder<? extends Long> bounded = new Holder<Long>();
Long lng = 1l;

unboundedArg(raw,lng);
unboundedArg(qualified,lng);
unboundedArg(unbounded,lng);
unboundedArg(bounded,lng);
}
}

还有就是:如果有做服务器端的前辈从这里路过,能否指点一下java做服务器端,新手该是怎样的一个学习路线??十分感谢。。。
java泛型

------解决方案--------------------
第一个类没不用修改,主要问题应该在第二个类上面,下面是我修改的代码

public Holder<? extends List<?>> test(Holder<? extends List<?>> holl)   //修改的地方
{
return holl;
}

或者按照下面的代码

public Holder<?> test(Holder<?> holl)   //修改的地方
{
return holl;
}


至于为什么这么写,我也是不是很深入的理解,但是我可以说我对这个问题的理解吧,如果谁有不同的观点可以指出来
对于通配符“?”可以看成是一种参数类型,那List<?>就不能看成是一种参数类型,也不能当成通配符来使用,楼主把List<?>当成通配符来使用,当然就会造成类型不匹配,如果是"? extends List<?>"又不一样了,这是使用的是通配符“?”,这个“?”继承了List<?>,
感觉我这段话里面也有问题
------解决方案--------------------
把test方法改成static void test(Holder<? extends List<? extends Number>> holl),那么语句
test(hl1)就不会报错。hl1看起来是Holder<List<Integer>>类型,但它由li作为参数初始化,而li实际上是ArrayList<Integer>类型的。所以hl1实际上是Holder<ArrayList<Integer>>类型的。这就是为什么是? extends List。?改成? extends Number的原因是?单独使用表示? extends Object,因为Integer不是Object的直接子类,所以必须写成? extends Number。

test(hld)报错的原因是类型根本不一样,除非写一个新的test1方法来适应hld的类型。