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

在上面的代码中,当 MyService 声明谈论给定类型的特定子类型时,Java 泛型实现如何允许 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);
}

但是在这里你会得到一个运行时 ClassCastException 因为你MyClass2将列表中的元素转换MyClass1为不是MyClass2. for 循环需要遍历一个通用的超类或接口。

于 2012-06-15T12:52:46.323 回答