无法定义通用接口

时间:2009-01-08 23:39:01

标签: java generics

我一直在努力定义一个通用接口,但是我没有 实现我想要的。以下是该问题的简化示例。

假设我有一个通用的消息

public class Message<T> {

    private T content;

    public void setContent(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }

}

然后我想定义一个用于传输内容的接口:

public interface Transfer<Message<T>> {

    public void send(Message message);

}

问题是编译器不接受这个,并且总是抱怨 第二个'&lt;'性格,无论我尝试什么变化。 如何指定此接口以使其绑定到泛型类型(基于Message) 并且还可以访问参数化类型?

我的计划是使用以下界面:

public class Carrier<Message<T>> implements Transfer<Message<T>> {

    public void send(Message message) {
        T content = message.getContent();
        print(content);
    }

    public static void print(String s) {
        System.out.println("The string equals '" + s + "'");
    }

    public static void print(Integer i) {
        System.out.println("The integer equals " + i);
    }

    public static void main(String[] args) {
        Carrier<Message<String>> stringCarrier = new Carrier<Message<String>>();
        Message<String> stringMessage = new Message<String>("test");
        stringCarrier.send(stringMessage);

        Carrier<Message<Integer>> integerCarrier = new Carrier<Message<Integer>>();
        Message<Integer> integerMessage = new Message<Integer>(123);
        integerCarrier.send(integerMessage);
    }
}

我做了一些搜索和阅读(除了Angelika's generics faq之外的其他事情),但我无法判断这是不可能的,还是我做错了。

更新2009-01-16 :删除了“Thing”的原始用法,而不是“Message&lt; T&gt;” (之所以使用它是因为我能够编译而不会在接口上出现语法错误。)

3 个答案:

答案 0 :(得分:5)

在我看来,你想要:

public class Carrier<Thing extends Message<Foo>, Foo>
    implements Transfer<Thing>

这样编译器会知道thingMessage<Foo>,因此会有一个getContent()方法。

您需要将其用作:

Carrier<Message<String>, String>

但是你现在有点断绝了。您正在实施Transfer<Thing>,但是您尝试使用thing,就好像Message<Thing>查看您的send方法一样 - 您使用字符串和字符串调用它整数。这些类没有getContent()方法。

我怀疑您实际上应该实施Transfer<Message<Thing>>而不是Transfer<Thing>

答案 1 :(得分:0)

无论您如何解决泛型问题,您的代码都无法编译,因为您没有将T类型作为参数的打印方法。

我相信如果你想要你想要的功能,你将不得不做检查的实例。所以,在这种情况下,我不认为你从泛型类型中获得任何价值。

答案 2 :(得分:0)

您只需要为类指定T,然后使用Message&lt; T>为你的参数/返回类型。

public interface Transfer<T> {
    public void send(Message<T> message);
}

你不使用Message&lt;的原因T>是因为你在你的参数和返回类型中提供了'this is a message'。