【问题标题】:Trouble defining a generic interface定义通用接口的麻烦
【发布时间】:2009-01-08 23:39:01
【问题描述】:

我一直在努力定义一个通用接口,但我失败了 达到我想要的。以下是该问题的简化示例。

假设我有一个通用的 Message

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);

}

问题是编译器不接受这个,老是抱怨 第二个 '

我的计划是使用这个界面,如下所示:

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”的原始用法(使用它是因为我能够编译而不会出现语法错误界面)。

【问题讨论】:

  • 那么这个问题解决了吗?看起来 Jon Skeet 想通了,但您没有将他的答案标记为已接受。

标签: java generics


【解决方案1】:

它看起来像你想要的:

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

这样编译器就会知道thingMessage&lt;Foo&gt;,因此会有一个getContent() 方法。

您需要将其用作:

Carrier<Message<String>, String>

但你目前有点脱节。您正在实现Transfer&lt;Thing&gt;,但您正在尝试使用thing,就好像它是Message&lt;Thing&gt; 一样,看看您的send 方法——您使用字符串和整数调用它。这些类没有getContent() 方法。

我怀疑您实际上应该实施 Transfer&lt;Message&lt;Thing&gt;&gt; 而不是 Transfer&lt;Thing&gt;

【讨论】:

  • 是的,宾果游戏!我想将接口定义为“Transfer>”,这是我的第一种方法。但是,当我尝试编译器总是在第二个 ”是我编译的唯一方法。
【解决方案2】:

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

我相信如果您想要您正在寻找的功能,您将不得不进行检查。因此,在这种情况下,我认为您不会从泛型类型中获得任何价值。

【讨论】:

    【解决方案3】:

    您只需为类指定 T,然后将 Message 用于您的参数/返回类型。

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

    您不使用 Message 的原因是因为您在参数和返回类型中提供了“这是一条消息”上下文。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-27
      相关资源
      最近更新 更多