3

今天早上我问了一个类似的问题,以为我已经回答了,实际上实施了提议的解决方案,但它没有满足我的需求。所以这是我的全部问题:

我有以下课程:

// 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_OBJECTs 实际上是一个接口,例如Processable, 并让Apple,Chair等实现它。但是没有人知道客户想要处理什么,所以我宁愿不要强迫他们让他们的 POJO 实现一个Processabl接口,如果可能的话。

那么,我想要的 API 可能吗?如果是这样,怎么做?如果不是,那么为什么,以及我能得到的最接近它的位置是什么?提前致谢!

4

3 回答 3

3

类型参数列表中的每一项都需要是类型参数。在 ObjectProcessor 的类声明中,ProcessingMetadata<PROCESSABLE_OBJECT>不是泛型类型参数。

您可以将 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 > 
{ ... }
于 2013-06-27T16:31:44.327 回答
1

我认为在您的 api 中,开发人员会使用这一行

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

像这样

ProcessingMetadata<Apple> meta = appleProcessor.process(data);
于 2013-06-27T16:54:03.430 回答
0

类声明本身只接受类型参数声明,但您尝试将其放在ProcessingMetadata那里。

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);
于 2013-06-27T16:38:45.940 回答