首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java泛型强制兼容通配符

Java泛型强制兼容通配符
EN

Stack Overflow用户
提问于 2015-08-27 08:08:23
回答 3查看 1.4K关注 0票数 43

我有这些课。

代码语言:javascript
复制
class RedSocket {}
class GreenSocket {}
class RedWire {}
class GreenWire {}

我有一个类,它使用两个泛型类型

代码语言:javascript
复制
public class Connection<W, S> {}

其中W是电线型,S是套接字型。

我正在努力执行编译时间检查,以确保套接字和电线具有相同的颜色。

我试过这样做:

代码语言:javascript
复制
public class Connection<W extends Wire & Color, S extends Socket & Color> {}

interface Color {}

interface Red extends Color {}
interface Green extends Color {}

interface Socket {}
interface Wire {}

class RedSocket implements Socket, Red {}
class GreenSocket implements Socket, Green {}
class RedWire implements Wire,  Red {}
class GreenWire implements Wire, Green {}

但这并不能真正确保对于这两种泛型类型使用的Color是相同的,而且仍然允许我这样做:

代码语言:javascript
复制
public class Connection<W extends Wire & Color, S extends Socket & Color> {
    public static void main(String[] args) {
        new Connection<RedWire, GreenSocket>();
        new Connection<GreenWire, RedSocket>();
    }
}

( Radiodef 这里出色地解释了这种情况发生的原因)

如何执行编译时间检查,以确保套接字和电线具有相同的颜色?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-27 08:16:07

似乎最好用颜色来参数化SocketWire

代码语言:javascript
复制
interface Socket<C extends Color> {}
interface Wire<C extends Color> {}

class RedSocket implements Socket<Red> {}
class GreenSocket implements Socket<Green> {}
class RedWire implements Wire<Red> {}
class GreenWire implements Wire<Green> {}

这样,您就可以在Connection中引入多个泛型参数。

代码语言:javascript
复制
public class Connection<C extends Color, M extends Wire<C>, Q extends Socket<C>> {...}

像这样使用它:

代码语言:javascript
复制
new Connection<Red, RedWire, RedSocket>(); // ok
new Connection<Green, GreenWire, GreenSocket>(); // ok
new Connection<Green, GreenWire, RedSocket>(); // error
票数 56
EN

Stack Overflow用户

发布于 2015-08-27 09:18:47

作为塔吉尔·瓦列夫的回答的一个小变体:您可以去掉Connection类的第三个泛型参数,方法是使其构造函数private (或者可能是包可见),并提供一个工厂方法来创建Connection实例,以确保给定的WireSocket类型的Color类型是相同的:

代码语言:javascript
复制
class Connection<
    W extends Wire<? extends Color>, 
    S extends Socket<? extends Color>> 
{
    static <C extends Color, 
        W extends Wire<C>, 
        S extends Socket<C>> Connection<W, S> create()
    {
        return new Connection<W, S>();        
    }

    // Private constructor
    private Connection() {}
}

interface Color {}

interface Red extends Color {}
interface Green extends Color {}

interface Socket<C extends Color> {}
interface Wire<C extends Color> {}

class RedSocket implements Socket<Red> {}
class GreenSocket implements Socket<Green> {}
class RedWire implements Wire<Red> {}
class GreenWire implements Wire<Green> {}

public class CompatibleGenericsTest
{
    public static void main(String[] args)
    {
        Connection<RedWire, RedSocket> c0 = Connection.create(); // ok
        Connection<GreenWire, GreenSocket> c1 = Connection.create(); // ok
        Connection<GreenWire, RedSocket> c2 = Connection.create(); // error
    }
}
票数 36
EN

Stack Overflow用户

发布于 2015-08-28 15:55:10

试图混合-在一个任意的,适当的‘颜色’是一个典型的触发的整个继承和组合,又名。是一场辩论。Java这样的语言的普遍智慧是,在大多数情况下,应该倾向于组合而不是继承,以避免类似棘手通配符之类的事情。其他语言可以提供更多面向方面的编程方式。

虽然其他答案可能会帮助您获得正确的泛型,但我建议阅读关于这个主题的维基百科页面,并考虑是否真的需要在编译时执行颜色匹配,或者运行时构造函数检查是否会完成这项工作。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32243951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档