为什么java循环通用规范不允许转换"这个"进入通用实例

时间:2014-12-03 13:23:46

标签: java generics subclass

我可以创建循环泛型类依赖项,但不知何故我无法转换(没有编译错误)"这个"实例到通用引用。据我所知 - 在循环通用场景中创建破坏依赖的子类是不可能的。

public class P
{
    public static abstract class Network<C extends Client<N, C>, N extends Network<C, N>>
    {
        private C client;

        public void addClient(C client)
        {
            this.client = client;
        }
    }

    public static abstract class Client<N extends Network<C, N>, C extends Client<N, C>>
    {
        private N network;

        public void setNetwork(N network)
        {
            this.network = network;
        }

        public void attachOtherClient(C client)
        {
            network.addClient(client);
        }

        public void attachSelf()
        {
            attachOtherClient(this); //does not compile, but it is impossible to create subclasses that breaks this safety (i think)
        }
    }

    public static class TCP extends Network<MK, TCP>
    {

    }

    public static class MK extends Client<TCP, MK>
    {
        @Override
        public void attachSelf()
        {
            attachOtherClient(this); //compiles without problems
        }
    }

} 

我为我糟糕的英语道歉。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您应该使用更多泛型类:

public static abstract class Network<C extends Client<N, C>, N extends Network<C, N>>
{
    private Client<N, C> client; // <== generic type

    public void addClient(Client<N, C> client)
    {
        this.client = client;
    }
}

public static abstract class Client<N extends Network<C, N>, C extends Client<N, C>>
{
    private Network<C, N> network; // <== generic type

    public void setNetwork(N network)
    {
        this.network = network;
    }

    public void attachOtherClient(Client<N, C> client)
    {
        network.addClient(client);
    }

    public void attachSelf()
    {
        attachOtherClient(this); //  compiles & works: 'this' has type Client<N, C>, not C
    }
}

答案 1 :(得分:1)

C扩展了Client<N,C>,但Client<N,C>this的类型)不一定会扩展CattachOtherClient()的参数类型)。

  

但是不可能创建破坏这种安全性的子类

并非不可能。考虑

class TCP extends Network<MK, TCP> { }
class MK extends Client<TCP, MK> { }
class MK2 extends Client<TCP, MK> { }

这满足所有界限并正确编译。但在MK2内,如果您将this传递给attachOtherClient(),则会将MK2传递给期望为MK的内容,这显然是错误的。