额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泛型

解决方案 »

  1.   

    第一个类没不用修改,主要问题应该在第二个类上面,下面是我修改的代码public Holder<? extends List<?>> test(Holder<? extends List<?>> holl)   //修改的地方
    {
    return holl;
    }或者按照下面的代码public Holder<?> test(Holder<?> holl)   //修改的地方
    {
    return holl;
    }
    至于为什么这么写,我也是不是很深入的理解,但是我可以说我对这个问题的理解吧,如果谁有不同的观点可以指出来
    对于通配符“?”可以看成是一种参数类型,那List<?>就不能看成是一种参数类型,也不能当成通配符来使用,楼主把List<?>当成通配符来使用,当然就会造成类型不匹配,如果是"? extends List<?>"又不一样了,这是使用的是通配符“?”,这个“?”继承了List<?>,
    感觉我这段话里面也有问题
      

  2.   

    把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的类型。
      

  3.   

    多谢,因为解决了,所以就把这事给忘了;
    将test做如下修改即可:static void test(Holder<? extends List<?>> holl)原因是:如果参数是Holder<List<?>>,由于java泛型是用擦出实现的,所以List<?>等同于List<Object>,编译器将其解读为:我只需要List<Object>的参数,其他的就算是Object的子类也不是我要的,所以报错。          但如果用修改之后的声明法,则表明,我需要的是List<Object及其子类>,所以编译无误。
    PS:泛型还是有许多东西没弄清楚,比如说运行时擦出到第一边界到底到哪里才算是第一边界等还有许多莫名其妙的问题。不知道道友可有经验分享?
      

  4.   

    首先灰常感谢~,但是我觉得只要是子类就可以了,不必要是直接子类。这一点对于test(hld)的调用也是一样的。
    例外层主可以看下我在回复5楼时的理解,不知道是否有错漏之处?