-1

次のシナリオを検討してください。

/**
 * A sample interface.
 */
public interface MyInterface
{
}

/**
 * First sample implementation of the above interface.
 */
public class MyClass1 implements MyInterface
{
    public String toString()
    {
        return "[ My Class 1 ]";
    }
}


/**
 * Second sample implementation of the above interface.
 */
public class MyClass2 implements MyInterface
{
    public String toString()
    {
        return "[ My Class 2 ]";
    }
}


import java.util.Collection;

/**
 * A service interface that declares a generic method
 * returning a collection of subtype the interface defined above.
 */
public interface MyService
{
    public <T> extends MyInterface<Collection<T>> myMethod();

}

import java.util.Arrays;
import java.util.Collection;

/**
 * The implementation of the service interface 
 * that returns the generic type. 
 */
public class MyServiceImpl implements MyService
{

    @Override
    public Collection<MyInterface> myMethod()
    {
        return Arrays.asList(new MyClass1(), new MyClass2());
    }

}

import java.util.Collection;

/**
 * Simple main class to drive the point 
 * I would like raise in the query below.
 */
public class MyMain
{
    public static void main(String[] args)
    {
        MyService service = new MyServiceImpl();
        Collection<MyClass1> list = service.myMethod();
        // This works at runtime.
        System.out.println(list);
        for (MyClass1 obj : list)
        {
            // This throws ClassCastException at runtime.
            System.out.println(obj);
        }
    }
}

上記のコードで、Javaジェネリック実装は、MyService宣言が特定のタイプの特定のサブタイプについて話しているときに、MyServiceImplの実装がジェネリッククラスを返すことをどのように許可できますか?

4

2 に答える 2

1

正しいジェネリック型を追加した場合

public class MyMain {
    public static void main(String[] args) {
        MyService service = new MyServiceImpl();
        Collection<MyInterface> list = service.myMethod();
        // This works at runtime.
        System.out.println(list);
        for (MyInterface obj : list) {
            // This doesn't throw a ClassCastException
            System.out.println(obj);
        }
    }
}

私は得る

[[ My Class 1 ], [ My Class 2 ]]
[ My Class 1 ]
[ My Class 2 ]

例を警告なしにコンパイルしてClassCastExceptionをトリガーする方法がわかりません。

于 2012-06-15T12:25:02.647 に答える
0
System.out.println(list);

この行は、ジェネリック型がない場合にtoString()キャストされる両方の要素のメソッドを呼び出すだけなので、問題ありません。Object

for (MyClass1 obj : list)
{
   // This throws ClassCastException at runtime.
   System.out.println(obj);
}

MyClass2ただし、リスト内の要素をMyClass1のスーパークラスではないクラスにキャストしているため、ここではランタイムClassCastExceptionが発生しますMyClass2。forループは、一般的なスーパークラスまたはインターフェイスを反復処理する必要があります。

于 2012-06-15T12:52:46.323 に答える