Почему это приведение не генерирует предупреждение компилятора? - PullRequest
4 голосов
/ 27 января 2012

Почему следующий код Java не генерирует предупреждение компилятора, говорящее что-то вроде «Небезопасное приведение из SuperClass в SomeBaseClass»?

public abstract SuperClass
{
    static SuperClass create()
    {
        return new AnotherBaseClass();
    }

    private static class SomeBaseClass extends SuperClass
    {
        void print()
        {
            System.out.println("Hello World");
        }
    }

    private static class AnotherBaseClass extends SuperClass
    {
    }

    public static void main(String[] args)
    {
        SomeBaseClass actuallyAnotherClass = (SomeBaseClass)SuperClass.create();
        actuallyAnotherClass.print();
    }
}

Я использовал jdk1.6.0_25 / bin / javac на компьютере с Windows. Затмение Гелиос тоже не предупреждает об этом.

Вместо этого возникает исключение времени выполнения:

Исключение в потоке "main" java.lang.ClassCastException: SuperClass $ AnotherBaseClass не может быть приведен к SuperClass $ SomeBaseClass

Ответы [ 3 ]

8 голосов
/ 27 января 2012

Javac предупреждает только о небезопасных приведениях при использовании генериков. Здесь компилятор доверяет вам знать, что вы делаете:)

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

На самом деле, компилятор выдает ошибку, если приведение вообще невозможно, например, если тип возвращаемых методов create() будет AnotherBaseClass вместо SuperClass.

Так как он возвращает SuperClass, компилятор не знает, что на самом деле будет возвращено - он также может вернуть SomeBaseClass. Таким образом, он должен верить, что вы знаете, что вы делаете с этим составом.

Редактировать :

Чтобы получить предупреждение при приведении, вы можете попробовать использовать инструмент анализа кода, такой как Checkstyle . Однако обратите внимание, что эти инструменты, скорее всего, не могут или не проверяют иерархию классов и, следовательно, могут только предупреждать о (не примитивных) приведениях, используемых в целом. Таким образом, если вы используете библиотеку, которая требует приведения (например, если вы используете коллекции Apache Commons, которые еще не поддерживают универсальные шаблоны), вы получите много предупреждений.

В конце концов, программирование все еще является искусством , и вам все еще нужно знать, что вы делаете.

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

Это не предупреждение компилятора.Во время выполнения произошла ошибка при попытке преобразовать объект AnotherBaseClass в SomeBaseClass.

...