我在编写具有通用返回值的方法时遇到困难。我希望有一个方法,当使用MachineMorphology
实例调用时,返回M
类型的实例,其中M
是MachineMorphology
泛型类型。
这有可能实现吗?
MachineMorphology.java
public interface MachineMorphology<M extends Machine> {
Class<? extends M> getClazz();
}
ExtrusionMachinesMorphology.java
public final class ExtrusionMachinesMorphology<M extends Machine> implements MachineMorphology<M> {
public static final ExtrusionMachinesMorphology<Doser> DOSER = new ExtrusionMachinesMorphology<>(Doser.class);
public static final ExtrusionMachinesMorphology<Extruder> EXTRUDER = new ExtrusionMachinesMorphology<>(Extruder.class);
public static final ExtrusionMachinesMorphology<Blower> BLOWER = new ExtrusionMachinesMorphology<>(Blower.class);
public static final ExtrusionMachinesMorphology<Die> DIE = new ExtrusionMachinesMorphology<>(Die.class);
public static final ExtrusionMachinesMorphology<HaulOff> HAULOFF = new ExtrusionMachinesMorphology<>(HaulOff.class);
public static final ExtrusionMachinesMorphology<Winder> WINDER = new ExtrusionMachinesMorphology<>(Winder.class);
public static final ExtrusionMachinesMorphology<FilmMeasurer> MEASUSER = new ExtrusionMachinesMorphology<>(FilmMeasurer.class);
public static final ExtrusionMachinesMorphology<AirRing> AIR_RING = new ExtrusionMachinesMorphology<>(AirRing.class);
public static final ExtrusionMachinesMorphology GEC = null;
public static final ExtrusionMachinesMorphology UNDEFINED = null;
private final Class<M> clazz;
public ExtrusionMachinesMorphology(Class<M> clazz) {
this.clazz = clazz;
}
public Class<? extends M> getClazz() {
return clazz;
}
}
AbstractExtrusionPlant.java
public abstract class AbstractPlant<T extends PlantType, S extends PlantStatus, O extends PlantOperatorStatus, A extends Alarm>
extends ListenableObject<AlarmsListener<Machine, A>> {
[...]
private volatile HashMap<MachineMorphology, List<? extends Machine>> machines = new HashMap<>();
public synchronized <M extends Machine> M getMachine(MachineMorphology<M> morphology, int unitId) {
return getMachineByUnitId(getMachinesByMorphology(morphology), unitId);
}
public synchronized <M extends Machine> M getMachineByUnitId(List<M> machines, int unitId) {
return machines.stream().filter(machine -> machine.getUnitId() == unitId).findFirst().orElse(null);
}
public synchronized <M extends Machine> List<M> getMachinesByMorphology(MachineMorphology<M> morphology) {
return (List<M>) machines.get(morphology);
}
[...]
}
这应该是使用方法
Doser doser = plant.getMachine(ExtrusionMachinesMorphology.DOSER, 1);
但是编译器希望:
Doser doser = (Doser)plant.getMachine(ExtrusionMachinesMorphology.DOSER, 1);
答案 0 :(得分:2)
我相信您在询问Map是否可以返回具有不同泛型类型的对象。答案是否定的,这是不可能的,但你可以使用Morphology的类型在返回之前转换List:
public synchronized <M extends Machine> List<M> getMachinesByMorphology(MachineMorphology<M> morphology) {
Class<? extends M> machineType = morphology.getClazz();
return machines.get(morphology).stream().map(machineType::cast).collect(Collectors.toList());
}
更新:这是我用于测试可兼容性的完整文件:
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
class Machine {
int getUnitId() { return 0; }
}
class PlantType { }
class PlantStatus { }
class PlantOperatorStatus { }
class Alarm { }
class Doser extends Machine { }
class Extruder extends Machine { }
class Blower extends Machine { }
class Die extends Machine { }
class HaulOff extends Machine { }
class Winder extends Machine { }
class FilmMeasurer extends Machine { }
class AirRing extends Machine { }
interface AlarmsListener<M, A> { }
class ListenableObject<T> { }
interface MachineMorphology<M extends Machine> {
Class<? extends M> getClazz();
}
final class ExtrusionMachinesMorphology<M extends Machine> implements MachineMorphology<M> {
public static final ExtrusionMachinesMorphology<Doser> DOSER = new ExtrusionMachinesMorphology<>(Doser.class);
public static final ExtrusionMachinesMorphology<Extruder> EXTRUDER = new ExtrusionMachinesMorphology<>(Extruder.class);
public static final ExtrusionMachinesMorphology<Blower> BLOWER = new ExtrusionMachinesMorphology<>(Blower.class);
public static final ExtrusionMachinesMorphology<Die> DIE = new ExtrusionMachinesMorphology<>(Die.class);
public static final ExtrusionMachinesMorphology<HaulOff> HAULOFF = new ExtrusionMachinesMorphology<>(HaulOff.class);
public static final ExtrusionMachinesMorphology<Winder> WINDER = new ExtrusionMachinesMorphology<>(Winder.class);
public static final ExtrusionMachinesMorphology<FilmMeasurer> MEASUSER = new ExtrusionMachinesMorphology<>(FilmMeasurer.class);
public static final ExtrusionMachinesMorphology<AirRing> AIR_RING = new ExtrusionMachinesMorphology<>(AirRing.class);
public static final ExtrusionMachinesMorphology<?> GEC = null;
public static final ExtrusionMachinesMorphology<?> UNDEFINED = null;
private final Class<M> clazz;
public ExtrusionMachinesMorphology(Class<M> clazz) {
this.clazz = clazz;
}
public Class<? extends M> getClazz() {
return clazz;
}
}
public abstract class AbstractPlant<T extends PlantType, S extends PlantStatus, O extends PlantOperatorStatus, A extends Alarm>
extends ListenableObject<AlarmsListener<Machine, A>> {
private volatile HashMap<MachineMorphology<? extends Machine>, List<? extends Machine>> machines = new HashMap<>();
public synchronized <M extends Machine> M getMachine(MachineMorphology<M> morphology,
int unitId) {
return getMachineByUnitId(getMachinesByMorphology(morphology), unitId);
}
public synchronized <M extends Machine> M getMachineByUnitId(List<M> machines, int unitId) {
return machines.stream().filter(machine -> machine.getUnitId() == unitId).findFirst().orElse(null);
}
public synchronized <M extends Machine> List<M> getMachinesByMorphology(MachineMorphology<M> morphology) {
Class<? extends M> machineType = morphology.getClazz();
return machines.get(morphology).stream().map(machineType::cast).collect(Collectors.toList());
}
public static void main(String[] args) {
AbstractPlant<PlantType, PlantStatus, PlantOperatorStatus, Alarm> plant =
new AbstractPlant<PlantType, PlantStatus, PlantOperatorStatus, Alarm>() { };
Doser doser = plant.getMachine(ExtrusionMachinesMorphology.DOSER, 1);
}
}