2013-06-27 3 views
3

오늘 아침에 similar question에 물어 보았습니다. 제안 된 솔루션을 실제로 구현했는데 필요한 해결책을 찾지 못했다고 생각했습니다. 나는 다음과 같은 수업을이중 중첩 된 Java generics

: 그래서 여기 내 전체 문제의

// Objects to process. 
public class Apple { 
    private Color color; 
    private int numberOfSeeds; 
    // ... 
} 

public class Chair { 
    private Material madeOutOfMaterial; 
    private double price; 
    // ... 
} 

public class CellPhone { 
    private Manufacturer make; 
    private String model; 
    private boolean isSmartPhone; 
    // ... 
} 

// Contains the object that will be processed (an Apple, Chair, CellPhone instance, etc.) 
// as well as metadata info about the processing itself (timestamp, a UUID for tracking 
// purposes, etc.). 
public class ProcessingMetadata<PROCESSABLE_OBJECT> { 
    private PROCESSABLE_OBJECT result; 
    private Date processedOnDate; 
    private String uuid; 
    // ... 
} 

// Abstract base class for processing PROCESSABLE_OBJECTs. 
public abstract class ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> { 
    private String name; 

    public abstract ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data); 
} 

// One concrete processor. 
public class SimpleObjectProcessor extends ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> { 
    private Fizz fizz; 

    @Override 
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) { 
     // Processes data one way, and returns a PROCESSABLE_OBJECT. 
    } 
} 

// Another concrete processor. 
public class ComplexObjectProcessor extends ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> { 
    private Buzz buzz; 

    @Override 
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) { 
     // Processes data differently, and returns a PROCESSABLE_OBJECT. 
    } 
} 

그래서 최종 코드는 이러한 모든 클래스를 사용하는 것은 다음과 같습니다 것을 :

ObjectProcessor<ProcessingMetadata<Apple>> appleProcessor = 
     new ComplexObjectProcessor<ProcessingMetadata<Apple>>(); 
Data data = getData(); 

ProcessingMetadata<PROCESSABLE_OBJECT> meta = appleProcessor.process(data); 

Apple apple = meta.getResult(); 
Date processedOn = meta.getProcessedOnDate(); 
String uuid = meta.getUUID(); 

이는 "API입니다 "나는 개발자에게 노출되기를 원한다. Data을 잡고 입력 된 프로세서를 선택하고 데이터를 처리 한 다음 필요한 모든 메타 데이터를 가져옵니다.

문제는 내 ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>>이 유효하지 않다는 것입니다. 그것은 클래스 정의의 ProcessingMetadata 부분에 나에게 다음과 같은 컴파일러 오류가 있습니다 :

토큰 (들), 잘못된 구조 (들)

나는이 클래스와 연주 한 (및에

구문 오류 구체적인 서브 클래스들)을 제공하고 제네릭을 올바르게 설정하여 원하는 API를 제공하지 못하는 것 같습니다. 나는 실제로 Processable과 같은 PROCESSABLE_OBJECT을 필요로하며, Apple, Chair 등을 구현하고 있습니다. 그러나 클라이언트가 처리하고자하는 것을 알려주지 않으므로 POJO가 가능한 경우 모두 Processabl 인터페이스를 구현하도록 강요하지 않는 것을 선호합니다.

그래서 이 원하는 API를 사용할 수 있습니까? 그렇다면 어떻게? 그렇지 않다면, 왜, 그리고 내가 얻을 수있는 가장 가까운 것이 무엇입니까? 미리 감사드립니다!

+0

시도로이 라인

ProcessingMetadata<PROCESSABLE_OBJECT> meta = appleProcessor.process(data); 

을 사용 . – Kevin

+4

@Kevin : 도움 안됨 – jlordo

+0

@Kevin : this is Java – newacct

답변

3

형식 매개 변수 목록의 각 항목은 형식 매개 변수 여야합니다. ObjectProcessor의 클래스 선언에서는 제네릭 형식 매개 변수가 아닙니다.

PROCESSABLE_OBJECT를 매개 변수화 된 형식으로 지정한 다음 ProcessingMetaData를 다른 매개 변수화 된 형식으로 확장하는 형식을 지정할 수 있습니다.

public abstract class ObjectProcessor< 
    PROCESSING_METADATA extends ProcessingMetadata<PROCESSABLE_OBJECT>, 
    PROCESSABLE_OBJECT > 
{ ... } 

편집 :

귀하의 서브 클래스는 매개 변수 유형입니다. 이러한 유형 매개 변수를 클래스 자체에서 선언해야합니다. 그런 다음이를 사용하여 수퍼 클래스를 매개 변수화 할 수 있습니다.

public class SimpleObjectProcessor< 
    PROCESSING_METADATA extends ProcessingMetadata<PROCESSABLE_OBJECT>, 
    PROCESSABLE_OBJECT > 
extends ObjectProcessor< PROCESSING_METADATA,PROCESSABLE_OBJECT > 
{ ... } 
+0

감사합니다. @Andy Thomas (+1) - 콘크리트 프로세서의 정의 중 어떤 것이 표시되는지 알려주시겠습니까 (SimpleObjectProcessor 또는 ComplexObjectProcessor 등)? .)? –

+0

예 - 위의 편집을 참조하십시오. –

0

는 클래스 선언 자체는 단지 형식 매개 변수 선언이 필요하지만 당신은 거기 ProcessingMetadata를 넣어보십시오. `>>`: 나는 당신의 API를 생각

public abstract class ObjectProcessor<PROCESSABLE_OBJECT> { 
    private String name; 

    public abstract ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data); 
} 

public class SimpleObjectProcessor<PROCESSABLE_OBJECT> 
     extends ObjectProcessor<PROCESSABLE_OBJECT> { 
    private Fizz fizz; 

    @Override 
    public ProcessingMetadata<PROCESSABLE_OBJECT> process(Data data) { 
     // Processes data one way, and returns a PROCESSABLE_OBJECT. 
    } 
} 

ObjectProcessor<Apple> appleProcessor = new ComplexObjectProcessor<Apple>(); 
// Note: there is no PROCESSABLE_OBJECT here. Use the concrete type: 
ProcessingMetadata<Apple> meta = appleProcessor.process(data); 
1

는, 개발자는`>>`종료에 공간을 추가이

ProcessingMetadata<Apple> meta = appleProcessor.process(data);