Вывод общего типа Java, полученный из возвращаемого методом метода - PullRequest
5 голосов
/ 20 января 2012
public class TestCase {
    public static String compiles() {
        return getAction();
    }

    /*
    public static String doesntCompile1() {
        return (String) getAction();
    }

    public static String doesntCompile2() {
        return TestCase.<String> getAction();
    }
    */

    public static <T extends javax.swing.Action> T getAction() {
        return (T) null;
    }
}

Следует ли считать это ошибкой в ​​javac v1.6.0_22 и jdt v3.7.1?Мне кажется, так, потому что в других случаях компилятор фактически находит потенциальное исключение ClassCastException.В методе компиляции это вызовет ClassCastException во время выполнения.

Исходный код, который привел этот пример, не компилировался в javac, печатая следующее исключение.К сожалению, код примера, который я предоставил по какой-то причине, не будет генерировать эту ошибку.

type parameters of <T>T cannot be determined;
no unique maximal instance exists for type variable T with upper bounds

Ответы [ 2 ]

3 голосов
/ 20 января 2012

Я ожидал бы, что хороший компилятор сможет обнаружить ошибку, но в качестве оптимизации.Вы представляете конкретный случай более общего случая, подобного этому:

public class TestCase {
    public static TypeA methodA() {
        return methodB();
    }

    public static <T extends TypeB> T methodB() {
        return (T) null;
    }
}

Теперь, в общем, в этом нет ничего плохого, при условии:

  1. Если оба типа TypeA и TypeB оба являются классамитогда TypeB является суперклассом TypeA.
  2. TypeA или одного из подтипов TypeA наследуется от TypeB.

Теперь главное, что компилятор не является't проверка # 2, когда это возможно в этом случае.Но это только , потому что String - последний класс.Если класс не окончательный, # 2 всегда будет истинным, потому что потенциальные подклассы не известны во время компиляции.

Представьте, что вместо String вы использовали CharSequence.Тогда я ожидал бы, что все три будут компилироваться.Однако я не могу объяснить, почему в вашем примере второй и третий методы не компилируются.

Edit

А теперь я попробовал это с javac и обнаружил, что первый метод делаетне компилировать тоже.Вышеизложенное принимает предпосылку вашего вопроса, которая кажется ложной.Я получаю вводящую в заблуждение ошибку компиляции

Несовместимые типы.Требуется: java.lang.String.Найдено: T.

Этот ответ не отвечает на полный вопрос, а скорее объясняет, почему он не работает, а что-то вроде этого:

public static CharSequence compiles() {
    return (CharSequence)getAction();
}

делает.

0 голосов
/ 20 января 2012

Я не понимаю, в чем проблема / вопрос здесь. Ошибки, которые вы получаете, очевидны и ожидаемы.

Для метода doesntCompile1 мой компилятор сообщает мне

Невозможно разыграть из Действие в Строку

, что вполне ожидаемо - мы знаем, что метод возвращает T, что является Action, и мы знаем, что Action не может быть приведен к String.

Для метода doesntCompile2 мой компилятор сообщает мне

Несовпадение привязки: универсальный метод getAction () типа TestCase не применим для аргументов (). Предполагаемый тип String не является допустимой заменой ограниченного параметра

, что в основном та же причина, что и выше

Что вы ожидали от этого?

...