ClassCastException при использовании varargs и generics

Я использую java generics и varargs.

Если я использую следующий код, я получу ClassCastException, хотя я вообще не использую касты.

Что еще более странно, если я запускаю это на Android (dalvik), исключение не сопровождается трассировкой стека, а если я меняю интерфейс на абстрактный класс, переменная исключения e оказывается пустой.

Код:

public class GenericsTest {
    public class Task<T> {
        public void doStuff(T param, Callback<T> callback) {
            // This gets called, param is String "importantStuff"

            // Working workaround:
            //T[] arr = (T[]) Array.newInstance(param.getClass(), 1);
            //arr[0] = param;
            //callback.stuffDone(arr);

            // WARNING: Type safety: A generic array of T is created for a varargs parameter
            callback.stuffDone(param);
        }
    }

    public interface Callback<T> {
        // WARNING: Type safety: Potential heap pollution via varargs parameter params
        public void stuffDone(T... params);
    }

    public void run() {
        Task<String> task = new Task<String>();
        try {
            task.doStuff("importantStuff", new Callback<String>() {
                public void stuffDone(String... params) {
                    // This never gets called
                    System.out.println(params);
                }});
        } catch (ClassCastException e) {
            // e contains "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;"
            System.out.println(e.toString());
        }
    }

    public static void main(String[] args) {
        new GenericsTest().run();
    }
}

Если вы запустите это, то получите ClassCastException, что Object не может быть приведен к String с трассировкой стека, указывающей на недопустимый номер строки. Является ли это ошибкой в Java? Я тестировал это в Java 7 и Android API 8. Я сделал обходной путь (закомментировал doStuff-метод), но кажется глупым делать это таким образом. Если я убираю varargs (T... ), все работает нормально, но моя фактическая реализация вроде как нуждается в этом.

Stacktrace от исключения:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
    at GenericsTest$1.stuffDone(GenericsTest.java:1)
    at GenericsTest$Task.doStuff(GenericsTest.java:14)
    at GenericsTest.run(GenericsTest.java:26)
    at GenericsTest.main(GenericsTest.java:39)
5
задан murgo 30 January 2012 в 00:30
поделиться