2016-08-26 5 views
2

一般的な戻り値を持つメソッドを作成するのが難しいです。私はMachineMorphologyインスタンスで呼び出された場合、タイプMのインスタンスを返します。MMachineMorphologyジェネリックタイプです。一般的な戻り値を持つメソッド

これは可能ですか?

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

私はジェネレータを呼び出すときに、私はモルフォロジーとunitIdを指定する必要があるので、ジェネレータマシンのリスト(HashMapでMachineMorphologyでオーダーされたクラス)を持つ必要があるため、Factoryパターンは私の場合には適していないと思います。マシンのインスタンスがキャストされるようにするには –

+0

あなたの質問に答えがあったら、fウナギはそれを答えとして加えることを奨励した。解決策があることを示すためにタイトルに「解決済み」を使用しないでください。答えを受け入れるだけで十分です。 – Makoto

答えて

1

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 (M) 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()); 
} 

更新:ここで私はテストcompilabilityに使用する完全なファイルがあります:

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); 
    } 
} 
+0

形態とunitIdによってキャストされたマシンインスタンスを返すメソッドを持つためのアドバイスはありますか? は私の例のように: 'ドーザードーザー= plant.getMachine(ExtrusionPlantMachinesMorphology.DOSER、1);' –

+0

私はライン 'ドーザードーザー= plant.getMachineコンパイルすることができた(ExtrusionMachinesMorphology.DOSERを、1);'成功しました。しかし、あなたの質問では、 'ExtrusionPlantMachinesMorphology'ではなく、' ExtrusionMachinesMorphology'という名前のクラスを使用しました。あなたの目標を達成したかどうかは分かりません。 – VGR

+0

ExtrusionPlantMachinesMorphologyはクラスの古い名前です。コピー/ペーストエラーです テストコードが表示されますか? –

-1

は、単にあなたが意気消沈を持ちたい、それぞれの場合に(M)にキャストを追加します。

public class GenericDemo { 

    public static void main(String[] args) { 
     B b = get(); 
    } 

    static <T extends A> T get() { 
     return (T) new B(); 
    } 

    static class A { 

    } 

    static class B extends A { 

    } 
} 
+0

これは、理由でコンパイラの警告を生成します。それは安全ではありません。 – VGR

関連する問題