Java中的通用工厂方法

时间:2012-07-18 06:53:47

标签: java generics factory-pattern

我知道这个主题有几个主题,但我无法弄清楚我的问题在哪里。读取和搜索搜索结果我比以往更困惑。我希望我能把问题弄清楚。

我有一个消息类型层次结构,我有这些消息的通用处理器层次结构。到目前为止我跑了。现在我想为处理器实现一个工厂方法,并坚持我选择的通用方法。请看一下我的例子:

abstract class Message
{
    abstract int getTest();
}

class MyMessage1 extends Message
{
    @Override
    int getTest()
    {
        return 1;
    }
}

class MyMessage2 extends Message
{
    @Override
    int getTest()
    {
        return 2;
    }
}

interface Processor<T extends Message>
{
    void initialize(final T p_message);

    void doWork();
}

abstract class BaseMessageProcessor<T extends Message> implements Processor<T>
{
    private T message;

    @Override
    public void initialize(T p_message)
    {
        message = p_message;
    }

    protected T getMessage()
    {
        return message;
    }
}

class MyMessage1Processor extends BaseMessageProcessor<MyMessage1>
{
    @Override
    public void doWork()
    {
        // perfectly valid assignment
        MyMessage1 msg = getMessage();
        // do something
    }
}

class MyMessage2Processor extends BaseMessageProcessor<MyMessage2>
{
    @Override
    public void doWork()
    {
        // perfectly valid assignment
        MyMessage2 msg = getMessage();
        // do something
    }
}

到目前为止,这是有效的并且按预期工作。但现在工厂出现了:

class ProcessorFactory
{
    <T extends Message> Processor<T> createProcessor(final Class<T> p_msgType)
    {
        if (p_msgType.equals(MyMessage1.class))
        {
            // Type mismatch: cannot convert from MyMessage1Processor to Processor<T>
            return new MyMessage1Processor();
        }
        else if (p_msgType.equals(MyMessage2.class))
        {
            // Type mismatch: cannot convert from MyMessage2Processor to Processor<T>
            return new MyMessage2Processor();
        }
        else
        {
            throw new Exception("Unsupported message type: " + p_msgType);
        }
    }
}

也许这是我在这里制造的一个愚蠢的失败,但我看不到它。如果有人能给我一个提示,我会很感激。

此致

塞巴斯蒂安

编辑: 好吧我的错。问题是我将编译器错误声明为注释为“默认语言环境”(例如,对于第二个返回语句,我得到了编译错误):

  

类型不匹配:无法从MyMessage2Processor转换为处理器

1 个答案:

答案 0 :(得分:2)

要了解失败的原因,您必须了解类型擦除的工作原理:

  

虽然您清楚地知道自己正在做正确的事情,但编译器并没有,最重要的是,它无法知道它的设计,因为信息已被取消

让我尝试进一步解释这个概念:由于类型擦除,类型T在编译时被转换为java.lang.Object,并且没有Java编译器的编译时信息,表示

如果a.getClass().equals(MyClass.class),则a.getClass()的类型为MyClass<MyClass>


重要:请尽量避免编写此代码,因为这样会导致设计糟糕。如果你不想死于臭虫和无法管理的代码,请不要强制使用类型安全的语言来使用类型安全的逻辑证据,而不是编译类型证据。 如果你在编译器中通过强制转换强制类型安全,那么有一天你会改变类结构并且忘记更改工厂,一切都编译得很好,但在运行时你会得到一个BOOM。

工厂方法通常是一种模式,用于向调用者隐藏生成对象的逻辑,如果最终出现这种情况,则可能意味着您没有正确使用泛型。写一个类并拥有干净的设计要好得多。

也许您可以添加一个额外的问题:如何以类型安全的方式实现此模式?