1

我正在尝试通用化返回通用基类的工厂方法。它有效,但我收到“BaseClass 是原始类型......”警告。

我已经阅读了有关通用方法的 Java 文档,但我仍然不太了解如何完成此操作。

这是一些代码:

第一类

//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...
}

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

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

问题是 getFormatter() 方法警告 BaseFormatter 是原始类型,它就是。我尝试了各种方法,例如 BaseFormatter 等。当然,我希望返回类型是通用的,就像调用方法中声明的 BaseFormatter 一样。

请注意,格式化程序类型不基于类类型。例如,并非所有整数值都使用 FooFormatter 进行格式化。可以通过两种或三种不同的方式格式化整数(或字符串或列表)。这就是参数 unrelatedInteger 的用途。

提前感谢您的任何反馈。

4

3 回答 3

0

学术语言中的某些类型系统可以表达所谓的依赖和。Java当然不能;那么,明智地,getFormatter 方法返回的对象的类型可能是什么?我们能做的最好的事情就是BaseFormatter< ? extends Object >,或者BaseFormatter< ? >简称,as Integerand Stringhave only Objectcommon。

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

于 2012-06-24T00:58:42.290 回答
0

您实际上是在说,类型化参数BaseFormatterunrelatedInteger作为参数传递给getFormatter方法的参数之间没有联系。

我收到其他警告:

Uncehcked Assignment: BaseFormatter to BaseFormatter<Integer>

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

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

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

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

于 2012-06-23T23:08:51.650 回答
0

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

public static BaseFormatter<T> getFormatter(Integer unrelatedInteger)

如果 getFormatter 是在 BaseFormatter 以外的另一个类中定义的,则使用:

public static BaseFormatter<?> getFormatter(Integer unrelatedInteger)
于 2012-06-23T18:46:56.990 回答