Java - 返回通用Base类型的Factory Method

时间:2012-06-23 18:29:15

标签: java generics

我试图对返回的工厂方法进行泛化 通用基类。它有效,但我得到了 " BaseClass是原始类型......"警告。

我已经阅读了关于通用方法的Java文档, 但是我还没有完全掌握如何做到这一点。

这里有一些代码:

第1课

//base abstract class
public abstract class BaseFormatter<T>
{
    public abstract String formatValue(T value);
}

第2课

//two implementations of concrete classes
public class FooFormatter extends BaseFormatter<Integer>
{
    @Override
    public String formatValue(Integer value)
    {
        //return a formatted String
    }
}

第3课

public class BarFormatter extends BaseFormatter<String>
{
    @Override
    public String formatValue(String value)
    {
        //return a formatted String
    }
}

单独类中的工厂方法

public static BaseFormatter getFormatter(Integer unrelatedInteger)
{
    if (FOO_FORMATTER.equals(unrelatedInteger))
        return new FooFormatter();
    else if (BAR_FORMATTER.equals(unrelatedInteger))
        return new BarFormatter();
    //else...
}

从代码中的其他地方调用Factory方法

BaseFormatter<Integer> formatter = getFormatter(someInteger);
formatter.formatValue(myIntegerToFormat);

问题是getFormatter()方法警告BaseFormatter是 原始类型,它是。我尝试过各种各样的东西,比如BaseFormatter 等。当然,我希望返回类型是通用的,如声明的那样 调用方法中的BaseFormatter。

请注意,格式化程序类型不基于类类型。例如不是所有的整数 值使用FooFormatter格式化。有两三种不同 可以格式化整数(或字符串或列表)的方式。这是什么的 param unrelatedInteger适用于。

提前感谢您的任何反馈。

3 个答案:

答案 0 :(得分:0)

如果在BaseFormatter中定义了getFormatter,则使用:

public static BaseFormatter<T> getFormatter(Integer unrelatedInteger)

如果getFormatter在另一个类中定义而不是BaseFormatter,则使用:

public static BaseFormatter<?> getFormatter(Integer unrelatedInteger)

答案 1 :(得分:0)

您真实地说,BaseFormatter的类型参数与作为unrelatedInteger方法的参数传递的getFormatter之间没有关联。

我收到了其他警告:

Uncehcked Assignment: BaseFormatter to BaseFormatter<Integer>

此警告比您指示的警告更糟糕。它警告此用户代码可能会尝试将BaseFormatter<String>插入BaseFormatter<Integer>,只有在运行时失败时才会注意到这一点......考虑用户不小心使用您的工厂方法,如:

BaseFormatter<Integer> myUnsafeFormatter =
        FormatterFactory.getFormatter(unrelatedIntegerForBarFormatter);

编译器无法将unrelatedInteger与返回的BaseFormatter的参数化类型相关联。

Alternitavely,我让用户明确使用具体的格式化程序构造函数。所有格式化程序共享的任何公共代码都可以放入FormatterUtils类(只是不要让那个utils类增长到很多......)。

答案 2 :(得分:0)

学术语言中的某些类型系统可以表达所谓的依赖和。 Java当然不能;那么明智的是,getFormatter方法返回的对象的类型是什么?我们所能做的最好的是BaseFormatter< ? extends Object >,或简称为BaseFormatter< ? >,因为IntegerString只有Object的共同点。

我认为最初的帖子引出了一个问题,为什么我们必须使用整数来决定返回什么格式化程序,如果调用者不知道格式化程序的类型,为什么调用者需要比{更强的变量类型? {1}}?