2017-01-29 3 views
1

이것은 간소화 된 버전에서 다른 사람의 질문을 해결하려고 시도한 것입니다. 반사적 (순환) 의존성이있는 클라이언트와 서버는 제네릭을 사용하여 수퍼 클래스에서 강력한 형식의 참조를 유지하려고 시도합니다. wish는 ClientType1 < -> ServerType2와 같은 임의의 하위 형식 구문 분석과 특정 형식에서만 발견되는 특수 메서드에 대한 강력한 형식의 호출에 대한 것이 었습니다.반사적 종속성을 가진 일반 클래스

이것은 서버에서 클라이언트까지 한 단계의 깊이에서만 작동하지만 그 클라이언트에서 서버로 다시 계속하려고하면 실패합니다. 임의의 수준의 강력한 형식의 호출을 허용하는 구문이 있습니까?

abstract class ServerBase<C extends ClientBase<?>> 
{ 
    ArrayList<C> clients = new ArrayList<C>(); 
} 
abstract class ClientBase<S extends ServerBase<?>> 
{ 
    S server; 
} 
class ClientType1<S extends ServerBase<?>> extends ClientBase<S> 
{ 
    public void clientType1Method() {} 
} 

class ServerType1<C extends ClientBase<?>> extends ServerBase<C> 
{ 

} 



public class Example { 
    public static void main(String[] args) { 
     ServerType1<ClientType1<?>> s = new ServerType1<>(); 
     s.clients.get(0).clientType1Method(); // Single depth level - OK 
     s.clients.get(0).server.clients.get(0).clientType1Method(); // level 2 - compiler error - undefined method  
    } 
} 

답변

2

제 생각에는 그러한 복잡한 참조가 실제로는 필요하지 않습니다.

실제로 의미하는 바는 클라이언트가 연결할 수있는 서버에 대한 참조를 보유하고 있다는 것입니다.

어떤 작업을해야하는 것입니다 :이 코드를 사용하여 작은 비틀기를 할 경우 반드시 작동

abstract class ServerBase<C extends ClientBase<? extends ServerBase>> 
{ 
    ArrayList<C> clients = new ArrayList<C>(); 
} 
abstract class ClientBase<S extends ServerBase<? extends ClientBase>> 
{ 
    S server; 
} 
1

. 당신이 실제 유형의 ? 대신 직접 입력하기 때문에

abstract class ClientBase<S extends ServerBase<?>> { 
    S server; 

    public abstract void clientMethod(); 
} 

.......

public static void main(String[] args) { 
    ServerType1<ClientBase<?>> s = new ServerType1<>(); 
    s.clients.get(0).clientMethod(); // Single depth level - OK 

    s.clients.get(0).server.clients.get(0).clientMethod(); 
    // second level - NO compiler error 
} 
+0

감사하지만, 그 의미는 아니었지만. 임의의 수준에서 작동해야하며 clientMethod는 각 파생 클래스 (예 : 다른 이름 또는 서명)에서 고유해야합니다. –

0

글쎄, 그것은 실패합니다.

ServerType1<ClientType1<ServerType1<ClientType1<?>>>> s = new ServerType1<>(); 
s.clients.get(0).clientType1Method(); 
s.clients.get(0).server.clients.get(0).clientType1Method(); 

대신 사용하면됩니다. 꽤 무의미하지만, s.clients.get(0).servers과 같다고 가정하면.

순환 의존성을 사용하는 경우에만 참조 할 수있는 명명 된 유형이있는 경우에만 사용할 수 있습니다.

public static <S extends ServerType1<ClientType1<S>>> void main(String[] args) { 
    ServerType1<ClientType1<S>> s = new ServerType1<>(); 
    s.clients.get(0).clientType1Method(); 
    s.clients.get(0).server.clients.get(0).clientType1Method(); 
    s.clients.get(0).server.clients.get(0).server.clients.get(0).clientType1Method(); 
    s.clients.get(0).server.clients.get(0).server.clients.get(0) 
        .server.clients.get(0).clientType1Method(); 
    s.clients.get(0).server.clients.get(0).server.clients.get(0) 
        .server.clients.get(0).server.clients.get(0).clientType1Method(); 
} 

대부분의 사용 사례에서는 실용적이지 않지만, S을 인스턴스화해야하는 즉시 실제 클래스가 필요합니다. 그러한 일반적인 구조가 정말로 필요한지 다시 생각해 봐야합니다. 그리고 메소드의 호출자와 관련이없는 도우미 유형 변수로 이러한 코드를 만드는 것을 고려한다면 클래스의 public API에 표시되지 않도록 private 메소드를 사용해야합니다.

+0

왜 그렇게 생각합니까? 그것은 올바르게 작동합니다. – Holger

+0

컴파일되지 않습니다. –

+0

글쎄, 내 jdk와 않습니다. 컴파일 오류가 발생하면 오류를 게시하거나 코드를 이해하려고 시도하십시오 (질문에 대한 답변에 코드를 게시하는 것이 목적 임). 그리고 무엇이 잘못되었는지 말해주십시오. – Holger