2017-12-30 39 views
-2

자바 제네릭 내에서 간 수준의 순환 참조를 만들 수있는 트릭이있다을 참조 :인스턴스화 원형 제네릭 클래스

public static class GenA<A extends GenA<A, B>, B extends GenB<A, B>> { 
    public B objB; 
} 
public static class GenB<A extends GenA<A, B>, B extends GenB<A, B>> { 
    public A objA; 
} 

내가 실제 개체의 인스턴스를하려고 :

GenA<GenA, GenB> genA = new GenA<>(); 

을 내가 컴파일 오류를 얻을 :

CircularRef.java:7: error: type argument GenA is not within bounds of type-variable A 
     GenA<GenA, GenB> genA = new GenA<>(); 
    where A,B are type-variables: 
    A extends GenA<A,B> declared in class GenA 
    B extends GenB<A,B> declared in class GenA 
CircularRef.java:7: warning: [rawtypes] found raw type: GenA 
     GenA<GenA, GenB> genA = new GenA<>(); 
    missing type arguments for generic class GenA<A,B> 
    where A,B are type-variables: 
    A extends GenA<A,B> declared in class GenA 
    B extends GenB<A,B> declared in class GenA 
CircularRef.java:7: warning: [rawtypes] found raw type: GenB 
     GenA<GenA, GenB> genA = new GenA<>(); 
    missing type arguments for generic class GenB<A,B> 
    where A,B are type-variables: 
    A extends GenA<A,B> declared in class GenB 
    B extends GenB<A,B> declared in class GenB 
CircularRef.java:7: warning: [unchecked] unchecked method invocation: constructor <init> in class GenA is applied to given types 
     GenA<GenA, GenB> genA = new GenA<>(); 
    required: no arguments 
    found: no arguments 
CircularRef.java:7: warning: [unchecked] unchecked conversion 
     GenA<GenA, GenB> genA = new GenA<>(); 
    required: GenA<GenA,GenB> 
    found: GenA 

나는 알고 해결 방법 :

0 같은 작품
public static class AdapterA extends GenA<AdapterA, AdapterB> { } 
public static class AdapterB extends GenB<AdapterA, AdapterB> { } 

:

AdapterA adA = new AdapterA(); 
AdapterB adB = new AdapterB(); 
adA.objB = adB; 
adB.objA = adA; 

어떻게 GenA/GenB 클래스를 직접 인스턴스화 할 수 있습니까?

이들은 abstract이 아닙니다. 나는 -Xlint:all도 경고가 없다고 말합니다.

EXTRA 나는))

을 닫습니다 싶은 코드와 지루 많은 사용자에 숨겨진 문제 이상 포함 질문 Defining typed hierarchy with Java generics and type self-referencing을 썼다 일반적인 원형 참조 선언을 선언에 대한 몇 가지 힌트에 있습니다 :

추가 기준 추가하는 UPDATE : 동일한

public static class GenA<A extends GenA<A, B, C>, B extends GenB<A, B, C>, C extends GenC<A, B, C>> { 
    public B objB; 
    public C objC; 
} 
public static class GenB<A extends GenA<A, B, C>, B extends GenB<A, B, C>, C extends GenC<A, B, C>> { 
    public A objA; 
    public C objC; 
} 
public static class GenC<A extends GenA<A, B, C>, B extends GenB<A, B, C>, C extends GenC<A, B, C>> { 
    public A objA; 
    public B objB; 
} 

문제 :

GenA<GenA, GenB, GenC> genA = new GenA<>(); 

과는 평소와 같이 해석 할 수있다

public static class AdapterA extends GenA<AdapterA, AdapterB, AdapterC> { } 
public static class AdapterB extends GenB<AdapterA, AdapterB, AdapterC> { } 
public static class AdapterC extends GenC<AdapterA, AdapterB, AdapterC> { } 

UPDATE 2 문제 렘 인스턴스화하지 않지만 형의 선언으로, 다음은 실패

GenA<GenA, GenB> genA; 
+0

당신은 할 수 없습니다 수 있습니다'도와주지 않을 GENA = 새로운 GENA <>();''도와주지 <도와주지 , GenB <...>>, GenB , GenB <...> >> GENA = 새로운 GENA <>()해야한다 ; ', 결국 무한히 길어질 수 있습니다. –

+0

** @ MadPhysicist **이 문제에 대해 생각했지만 Java Generic 사양에 익숙하지 않은 것은 확실하지 않았습니다 ... – gavenkoa

+0

중첩 된 제네릭 수준을 한 단계 더 추가하면 어떻게됩니까? 원시 형식 오류를 제거 할 수 있습니까? 작동하는 경우 어댑터 클래스를 갖는 것보다 낫습니다. –

답변

2
당신은 자신의 형태 변수와 방법에 인스턴스화 할 수 있습니다

이 단지의 질문을 펀트한다, 물론

<A extends GenA<A, B>, B extends GenB<A, B>> GenA<A, B> thing() { 
    return new GenA<>(); 
} 

"이 메소드를 호출하는 방법"으로 "어떻게 인스턴스화합니까?" 그리고 그 대답은 자체 형식 변수가있는 메서드에서 호출하거나 값을받는 형식으로 GenA<?, ?>을 사용하는 것입니다.

+0

예, 'GenA = 물건 <>();'과'GenA = 물건 <>();'모두 오류를 생성합니다 ... 또한'AdapterA xA = thing 오류 – gavenkoa

+0

아마도'thing <>()'이 유효한 구문이 아니기 때문일 수 있습니다. 한 가지 방법은 메서드 이름 앞에 오는 메서드에 대한 힌트를 입력하는 것입니다. 다른 경우 다이아몬드 운영자는 새로운 운영자에게만 적용됩니다. –