Почему ClassCastException является ошибкой во время выполнения?

1

Попытка:

class Base {
    public Base(){
    }
}

class Derived extends Base {
}

public class Main
{
    public static void main (String[] args)
    {
        Derived derived = (Derived) new Base();
    }
}

Вызывает CastClassException, но компилируется успешно. Комментарии по этому вопросу предполагают, что компилятор не может понять, какой тип new Base() имеет до выполнения, но почему это должно быть так? Я знаю, что в системах другого типа компилятор всегда может вывести тип любого выражения, а компилятор Java, конечно же, делает некоторый вывод типа, например, лямбда-выражения. И в какой-то момент он должен знать, какой тип имеет new Base(), если он собирается исправить правильный байт-код.

Есть ли теоретическое ограничение, которое мешает компилятору Java улавливать это до запуска программы или это выбор реализации?

  • 0
    Потому что это происходит во время выполнения ??
  • 0
    Приведение вещей говорит компилятору игнорировать его собственную информацию о типе и вместо этого доверять программисту. Вот почему это не улавливает это. Компилятор говорит: «Я знаю, что это типовая база, но программист сказал, что это производный. Они знают лучше».
Теги:
types

3 ответа

4
Лучший ответ
public static void main(String[] args) throws Exception {
    Derived derived = (Derived) getObject();
}

public static Base getObject() {
    if (Math.random() > 0.5) {
        return new Base();
    } else {
        return new Derived();
    }
}

Что теперь? Как компилятор узнает? Компилятор (в основном) ограничен статической информацией. Тип объекта - это динамическая информация.

  • 0
    Я не думал о таком случае. Мне все еще кажется более разумным отвергать неоднозначные случаи - есть ли веская причина написать актерский состав, который терпит неудачу в 50% случаев? Но я понимаю, почему, я думаю.
  • 0
    @Patrick Casting обычно не считается хорошей практикой. Мой пример должен был показать, что есть предел тому, что может знать компилятор. Языковые дизайнеры должны были отказаться от особого случая.
3

Любая рациональная реализация языка, разрешающего подклассирование, будет иметь возможность исключения исключения (или его эквивалента).

Сила схемы подкласса заключается в том, что у вас могут быть методы, которые работают на универсальном суперклассе, без необходимости знать конкретный подкласс. Но рано или поздно нужно будет выполнять операции, специфичные для подкласса, и для этого нужно сделать ссылку на подкласс. Если этот прилив ошибочен, потому что вы ошибочно принимаете действительный класс объекта, то логическое исключение должно логически возникать.

Вероятно, вы можете скрыть исключение cast за каким-либо механизмом, который, скажем, возвращает NULL, если объект не был правильным типом, но это просто заменяет одно исключение другим.

  • 0
    Да мне нравится , как C # использует в as .
1

Результатом new Base() является Base, которая в любом другом контексте может быть Derived. Компилятор не распространяет специальные знания, что в этом случае это действительно Base.

Есть ли теоретическое ограничение, которое мешает компилятору Java улавливать это до запуска программы или это выбор реализации?

Это выбор реализации, чтобы не делать особого случая.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню