泛型:输入变量?

Atm*_*ons 3 java generics

为了能够替代特定的实现,通常知道写

List<AnyType> myList = new ArrayList<AnyType>();
Run Code Online (Sandbox Code Playgroud)

代替

ArrayList<AnyType> myList = new ArrayList<AnyType>();
Run Code Online (Sandbox Code Playgroud)

这很容易理解,这样您可以轻松地将实现从ArrayList更改为LinkedList或任何其他类型的List.

嗯......这一切都很好,但由于我不能直接实例化"List",因此我需要输入

public List<AnyType> getSpecificList()
{
    return new ArrayList<AnyType>();
}
Run Code Online (Sandbox Code Playgroud)

这使得以前的模式毫无意义.如果我现在想用LinkedList而不是ArrayList替换实现怎么办?它需要在两个位置上进行更改.

有可能有这样的东西(我知道语法绝对不正确)?

public class MyClass<T>
{
    Type myListImplementation = ArrayList;

    List<T> myList = new myListImplementation<T>();

    public List<T> getSpecificList()
    {
        return new myListImplementation<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许我简单地将单词"ArrayList"更改为"LinkedList",一切都很好.我知道这两个列表可能有不同的构造函数,这不会"按原样"工作.我真的不想添加第二个类型参数来指定正在使用的列表实现.

是否有任何干净的机制来解决这个问题?^

在此先感谢和最好的问候Atmocreations

Juh*_*älä 14

为什么不使用某种工厂模式而不是直接实例化特定的列表实现.然后,您需要在工厂方法内的一个位置更改列表实现.

例如,您从以下开始:

 List<T> createList() {
     return new ArrayList<T>();
 } 

 List<T> myList1 = createList();
 List<T> myList2 = createList();
Run Code Online (Sandbox Code Playgroud)

稍后,如果您决定需要链接列表,则只需更改createList()的实现,其余代码保持不变.

List<T> createList() {
    return new LinkedList<T>();
}
Run Code Online (Sandbox Code Playgroud)


And*_*yle 8

嗯 - 据我了解你的问题,你想做的事情已经成为可能(与泛型无关).

在实际进行构造函数调用时,您总是需要给出列表(或任何类)的确切类型,这是不可避免的.同样,您始终可以避免在其他任何地方使用特定内容(将其存储在变量中,从方法返回,将其作为方法参数传递等).在你的情况下,你已经这样做 - 通过myList简单地声明一个List,如果你改变你存储在其中的具体类列表,你不需要改变它的声明类型.

我认为你的问题可能是因为你在同一个类中创建了两个不同的列表(但两者都是相同的类型),并且你想要抽象出来.您可以使用工厂类型模式轻松完成此操作; 无论是使用单独的工厂,还是在您的情况下,只需更换myList声明

List<T> myList = getSpecificList();
Run Code Online (Sandbox Code Playgroud)

编辑 - 出于兴趣,你可以得到最接近原始建议修复的东西是使用反射:

public class MyClass<T>
{
    Class<? extends List<T>> myListClass = ArrayList.class;

    List<T> myList = myListClass.newInstance();

    public List<T> getSpecificList()
    {
        return myListClass.newInstance();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是不要这样做 - 它是缓慢的,不灵活的,不寻常的(对于其他开发人员来说太难了)在这种情况下完全没有必要......

双重编辑:哦,你必须处理一大堆基于反射的检查异常,我将这些异常作为练习留给读者,以防你感到受到诱惑.;-)


Kei*_*all 5

如果我现在想用LinkedList而不是ArrayList替换实现怎么办?它需要在两个位置上进行更改.

不,你不会.您可以单独更改每个位置.即,其中一个分配可以是LinkedList,另一个可以是ArrayList.