你好,谢谢你的回复!可是依然有个疑问:
既然已经声明了T extends Object, String又是Object的子类, 为什么将add的时候还需要进行一次强制转换呢?
泛型的目的之一是不是为了避免强制转换?

解决方案 »

  1.   

    这样倒是成功了: T x = (T)new String("x");
    add(x);
    不过感觉还是很奇怪,
    搬个板凳坐等大神来解释吧good luck
      

  2.   

    想想如果你定义Test123<Integer> test = new Test123<>();,那么类型形参T就为Integer,test里调用add的时候实参类型确是String,你觉得编译器会让你通过编译吗?
      

  3.   

    我感觉我们的关注点关注错了,
    比如有下面的类
    A extends AA
    如果一个方法需要一个<? extends AA>的参数
    那么,直接写add(AA x){}就行了吧
    good luck
      

  4.   

    强转只是勉强让编译通过,运行的时候,如果你的类型形参不是String或Object,你就等着编译器给你一个ClassCastException吧。
      

  5.   

    import java.util.LinkedList;public class Test123<T extends Object> extends LinkedList<T> {
    private static final long serialVersionUID = 1L;

    public boolean add(T string) {
    return (!contains(string)) && (super.add(string));
    } public void test(){
    add(new Object());
    }

    public static void main(){
    Test123<Integer> test = new Test123<Integer>();
    test.add(new Integer(2));
    }
    }
    谢谢你的回复!
    add(new Object());这样也编译通不过。
      

  6.   

    import java.util.LinkedList;public class Test123<T extends Object> extends LinkedList<T> {
    private static final long serialVersionUID = 1L;

    public boolean add(T obj) {
    return (!contains(obj)) && (super.add(obj));
    } public void test(){
    add(new Object());//这里报错The method add(T) in the type Test123<T> is not applicable for the arguments (Object)
    }

    public static void main(String[ ] args){
    Test123<String> test = new Test123<String>();
    test.add(new String("UUUU"));//这里不报错
    }
    }
      

  7.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
      

  8.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
    因为T的类型还无法确定,上面打错了。
      

  9.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
    因为T的类型还无法确定,上面打错了。
    谢谢你的回复!
    T的上界是Object,在编译的时候至少可以确定T是Object或者Object的子类,在test()里面加入一个Object类型的对象应该是符合逻辑的吧?
      

  10.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
    因为T的类型还无法确定,上面打错了。
    谢谢你的回复!
    T的上界是Object,在编译的时候至少可以确定T是Object或者Object的子类,在test()里面加入一个Object类型的对象应该是符合逻辑的吧?
    我只想问你一个问题:
    Integer i = new Object();
    比如上面这行代码,Integer也是Object的子类。那么就可以把父类引用赋值给子类的引用了?
    很明显编译不过。但是:
    Integer i = (Integer)new Object();
    这样没问题,但是你会得到一个转型异常。因为Object它不是一个Integer。
    Test123<String> t = new Test123<>();
    t.test();
    t.add("abc");
    现在T是String,你调用test的时候,就相当于把Object赋值给了String。但Object不是String。如果你还不能理解,那我也帮不到了。
      

  11.   

    Integer i = new Object();
    看到这句的时候理解了!需要子类的地方不能赋值父类。多谢!
      

  12.   

    public class UsersList<T extends User> extends LinkedList<T>{
    public boolean add(T obj) {
    return (!contains(obj)) && (super.add(obj));
    }}
    再请教一下您,如果要实现上面的功能,应该如何修改?super.dd(obj)编译不通过。
      

  13.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
    因为T的类型还无法确定,上面打错了。
    谢谢你的回复!
    T的上界是Object,在编译的时候至少可以确定T是Object或者Object的子类,在test()里面加入一个Object类型的对象应该是符合逻辑的吧?
    我只想问你一个问题:
    Integer i = new Object();
    比如上面这行代码,Integer也是Object的子类。那么就可以把父类引用赋值给子类的引用了?
    很明显编译不过。但是:
    Integer i = (Integer)new Object();
    这样没问题,但是你会得到一个转型异常。因为Object它不是一个Integer。
    Test123<String> t = new Test123<>();
    t.test();
    t.add("abc");
    现在T是String,你调用test的时候,就相当于把Object赋值给了String。但Object不是String。如果你还不能理解,那我也帮不到了。
    public class UsersList<T extends User> extends LinkedList<T>{
    public boolean add(T obj) {        
    return (!contains(obj)) && (super.add(obj));  }
    } 再请教一下您,如果要实现上面的功能,应该如何修改?super.dd(obj)编译不通过。
      

  14.   

    我的意思是说在test里面调用add这样的写法是错的,除了add(null)其它的都不行。泛型类的设计主要用于处理一些与类型无关的对象,但是你调用add(new X);就对类型有关了,因为X的类型还无法确定。
    因为T的类型还无法确定,上面打错了。
    谢谢你的回复!
    T的上界是Object,在编译的时候至少可以确定T是Object或者Object的子类,在test()里面加入一个Object类型的对象应该是符合逻辑的吧?
    我只想问你一个问题:
    Integer i = new Object();
    比如上面这行代码,Integer也是Object的子类。那么就可以把父类引用赋值给子类的引用了?
    很明显编译不过。但是:
    Integer i = (Integer)new Object();
    这样没问题,但是你会得到一个转型异常。因为Object它不是一个Integer。
    Test123<String> t = new Test123<>();
    t.test();
    t.add("abc");
    现在T是String,你调用test的时候,就相当于把Object赋值给了String。但Object不是String。如果你还不能理解,那我也帮不到了。
    public class UsersList<T extends User> extends LinkedList<T>{
    public boolean add(T obj) {        
    return (!contains(obj)) && (super.add(obj));  }
    } 再请教一下您,如果要实现上面的功能,应该如何修改?super.dd(obj)编译不通过。
    编译器的错误是什么,JDK7下面是可以通过的。