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);
}
実行できました。。。予想通りの展開になりました。
