C#3.0でジェネリックスを使用していた人がJava6でジェネリックスを使用すると...(4)
こんにちは。受託開発担当(ここでは雑記担当)のMasaです。
前回は C# で検証したので、今回は Java で検証します。
最終回です。
前々回作成した MyObject1 、 MyObject2 クラスにプロパティとデバッグ用メソッドを追加します。
public class MyObject1 extends MyObject { private String company; public String getCompany() { return company; } public MyObject1() { } public MyObject1(String name, String company) { super(name); this.company = company; } public String toString() { return "名前は、" + this.getName() + "です。企業は、" + this.getCompany() + "です。"; } } public class MyObject2 extends MyObject { private String value; public String getValue() { return value; } public MyObject2() { } public MyObject2(String name, String value) { super(name); this.value = value; } public String toString() { return "名前は、" + this.getName() + "です。値は、" + this.getValue() + "です。"; } }
次はジェネリックなクラスです。C# と同様にイベントリスナー風の何かを作成します。
public interface MyObjectContainer<T extends MyObject> { T getInstance(); }
上記インタフェースを実装したクラスを追加します。C# と同様に Test クラスにプライベートクラスを追加しちゃいます。
private class MyObject1Container implements MyObjectContainer<MyObject1> { @Override public MyObject1 getInstance() { return new MyObject1("Java", "Sun"); } } private class MyObject2Container implements MyObjectContainer<MyObject2> { @Override public MyObject2 getInstance() { return new MyObject2("Java", "6"); } }
MyObjectContainer クラスを格納するリストを追加します。C# と同様にクラスを分けます。
予想通りビルドエラーです。
] public class MyObjectTest { private List myObjectContainerList; public <T extends MyObject> void AddMyObjectContainer(MyObjectContainer<T> container) { if (myObjectContainerList == null) myObjectContainerList = new ArrayList(); myObjectContainerList.add(container); } public <T extends MyObjectContainer<E>, E extends MyObject> void execute() { for (Object container : myObjectContainerList) { if (container instanceof MyObjectContainer<E>) { // ← エラー System.out.println(((MyObjectContainer<E>) container).getInstance().toString()); } } } }
しょうがないので引数で型を渡します。
//public <T extends MyObjectContainer<E>, E extends MyObject> void execute() public <T extends MyObjectContainer<E>, E extends MyObject> void execute(Class<T> t) { for (Object container : myObjectContainerList) { //if (container instanceof MyObjectContainer<E>) { if (t.isInstance(container)) { System.out.println(((MyObjectContainer<E>) container).getInstance().toString()); } } }
準備が整ったので、Test クラスにテストメソッドを追加し、実行します。
static void Main(string[] args) { Test test = new Test(); MyObjectTest myObjectTest = new MyObjectTest(); myObjectTest.AddMyObjectContainer(test.new MyObject1Container()); myObjectTest.AddMyObjectContainer(test.new MyObject2Container()); System.out.println("Execute(MyObject2Container<MyObject1>)が呼ばれるはずです。"); myObjectTest.execute(MyObject1Container.class); System.out.println("Execute(MyObject2Container<MyObject2>)が呼ばれるはずです。"); myObjectTest.execute(MyObject2Container.class); }
実行できました。。。予想通りの展開になりました。