3

我知道这个主题有几个线程,但我不知道我的问题出在哪里。上下翻阅搜索结果,我比以往任何时候都更加困惑。我希望我能把我的问题说清楚。

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

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 转换为 Processor

4

1 回答 1

2

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

虽然您清楚地知道自己在做正确的事情,但编译器却不知道,最重要的是,对于设计,编译器不知道,因为信息已被取消

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

如果a.getClass().equals(MyClass.class)thena.getClass()将是类型MyClass<MyClass>


重要提示:请尽可能避免编写此代码,因为这会导致糟糕的设计。如果您不想死在错误和无法维护的代码的地狱中,请不要强制类型安全语言使用类型安全的逻辑证据并且不要编译类型证据。如果你在编译器中强制类型安全,你就有可能有一天你改变了类结构而你忘记了改变工厂,一切都编译得很好,但在运行时你会得到一个 BOOM。

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

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

于 2012-07-18T07:23:59.337 回答