通用类型创建者

时间:2012-10-15 17:35:11

标签: java generics casting

  

可能重复:
  Java Generics: Cannot cast List<SubClass> to List<SuperClass>?

我想在某个基类上创建函数,创建它的继承类。

我试过这个:

class BaseFormat
{
    // Some variables

    public BaseFormat(string txt)
    {
        // Do something
    }

    public static <T> ArrayList<T extends BaseFormat> getTextFormat(String[] txt)
    {
        ArrayList<T> list = new ArrayList<T>();
        for (int i = 0; i < txt.length; i++)
        {
            list.add(new T(txt[i])); // ERROR
        }
        return list;
    }
}

class FooFormat extends BaseFormat
{
    // Some variables

    public FooFormat (string txt)
    {
        // Do something
    }
}

而且:

class BaseFormat
{
    // Some variables

    public BaseFormat(string txt)
    {
        // Do something
    }

    public static ArrayList<BaseFormat> getTextFormat(String[] txt)
    {
        ArrayList<T> list = new ArrayList<T>();
        for (int i = 0; i < txt.length; i++)
        {
            list.add(new BaseFormat(txt[i]));
        }
        return list;
    }
}

但是当我尝试投射数组时,我收到一个错误。这是我的代码:

String[] txts = ...; // Some texts
ArrayList<FooFormat> list = (ArrayList<FooFormat>) BaseFormat.getTextFormat(txts); // Casting ERROR

那我怎么能这样做,但仍然保持通用?

4 个答案:

答案 0 :(得分:0)

尝试做

  ArrayList<BaseFormat> list = (ArrayList<BaseFormat>) BaseFormat.getTextFormat(txts);

然后在迭代时,您可以通过检查instanceOf运算符

将项目向下转换为FooFormat

答案 1 :(得分:0)

您是否尝试按以下方式执行操作

class BaseFormat { }

class FooFormat extends BaseFormat { }

class FormatUtils {
    public static <T extends BaseFormat> List<T> getTextFormat(String[] txt, Class<T> clazz) {
        List<T> list = new ArrayList<T>();
        //... 
                T t = clazz.newInstance(); //create instance using reflection
                //...
        return list;
    }
}

并且

List<FooFormat> list = FormatUtils.getTextFormat(new String[]{}, FooFormat.class);

答案 2 :(得分:0)

因此,您正在混合使用动态类型的泛型和继承,这允许重写方法。你真正想要的是将创建包装的字符串与创建列表分开。

class BaseFormat
{
  // derived classes override this method to provide their own implementations
  public abstract BaseFormat wrapText(String[] txt);

  public ArrayList<? extends BaseFormat> getTextFormat(String[] txt)
  {
    ArrayList<? extends BaseFormat> list = new ArrayList<BaseFormat>();
    for (int i = 0; i < txt.length; i++)
    {
        list.add(wrapText(txt);
    }
    return list;
  }
}

答案 3 :(得分:0)

您必须将类型作为参数传递给静态方法,然后可能使用反射来调用Class.newInstance。类型擦除意味着编译后你不会有一个具体的类型T,这就是为什么你不能编译new T(...)