I asked a similar question this morning, thought I had it answered, actually implemented the proposed solution, and it failed to do what I need. So here's my full problem:
I have the following classes:
// 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.
}
}
So that the final code, using all of these classes looks like this:
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();
This is the "API" that I want exposed to the developer. Grab some Data, select a typed processor, process the data, and get all the metadata you need.
The problem is that my ObjectProcessor<ProcessingMetadata<PROCESSABLE_OBJECT>> isn't legal. It gives me the following compiler error on the ProcessingMetadata portion of the class definition:
Syntax error on token(s), misplaced construct(s)
I have played with this class (and its concrete subclasses) all morning, and can't seem to get generics set up correctly to give me the API that I want. I'm open to requiring the PROCESSABLE_OBJECTs to actually being an interface, such as Processable, and having Apple, Chair, etc. implement it. But there's no telling what the client is going to want to process, and so I'd prefer not to force them to make their POJOs implement a Processabl interface, if at all possible.
So, is my desired API possible? If so, how? If not, then why, and what is the closest I can get to it? Thanks in advance!
>>:> >.