参数化方法在java中返回泛型类成员

时间:2016-10-13 01:02:30

标签: java generics

为什么不允许使用以下代码?

class MyClass {
    List<? extends Something> list;
    <T extends Something> List<T> myFunc(T t) {
        list = new ArrayList<T>(); // ok
        list.add(t); // error
        return list; // error
    }
}

如何在保持相同的同时修复代码?即类成员list仅接受Something的子类和myFunc()的子类相同的对象?

3 个答案:

答案 0 :(得分:2)

我认为Generic <T>声明可以在课程级别完成。

据我所知,这是因为通配符?不能用作类型参数。

  

通配符永远不会用作泛型方法调用,泛型类实例创建或超类型的类型参数

所以我得到的是Java不会知道<T extends Something>以及即使它具有扩展相同的上下文的列表,也不能确保它是相同类型的。

一个可能的(可能不是你想要的)解决方案将在类级别声明Generic。

如果我们这样做可能会有效:

class Abc <T extends Something>{
    List<T> list;
    List<T> myFunc(T t) {
        list = new ArrayList<T>(); // ok
        list.add(t); 
        return list; 
    }
}

我希望它有所帮助。

答案 1 :(得分:0)

在任何地方使用之前,您必须在某处定义T类型参数。理想情况下,您应该使用类声明来定义它。因为你已经在课堂上的很多地方使用过它。如果T仅用于方法范围,则可以使用方法签名定义它。

您无法修改上限 <T extends Something>无界 <?>类型实例。

这意味着,不允许向List<?>(无界列表)和List<T extends Something>添加任何元素。

如果要使其正常工作,可以使用List的下限类型参数。

class MyClass<T super Something> {
    List<T super Something> list;
    <T super Something> List<T> myFunc(T t) {
        list = new ArrayList<T>(); // ok
        list.add(t); 
        return list; 
    }
}

答案 2 :(得分:0)

您无法list.add(t);,因为list的类型为List<? extends Something>t的类型为T,并且无法知道T是否? 1}}是return list;代表的未知类型的子类型。

同样,您无法执行list,因为List<? extends Something>的类型为List<T>,列表的返回类型为List<? extends Something>,无法知道{是否{ {1}}是List<T>

我认为您的想法是将List<T>放入变量中,因此您知道它是List<T>,并且您尝试将其用作List<T>。但这不是它的工作原理。 list的类型为List<? extends Something>。无论你输入什么,都不会改变变量的类型,变量的任何使用仍然必须基于它的编译时类型。

如果你想在后面的方法中使用你为List<T>创建的对象,你需要保留一个List<T>类型的变量来指向它,如下所示:< / p>

<T extends Something> List<T> myFunc(T t) {
    List<T> tempList = new ArrayList<T>();
    list = tempList;
    tempList.add(t);
    return tempList;
}