Upcasting разрешен в Java, однако downcasting дает ошибку компиляции.
Ошибка компиляции может быть удалена путем добавления приведения, но она все равно прервется во время выполнения.
В этом случае, почему Java допускает даункастинг, если он не может быть выполнен во время выполнения?
Есть ли практическое применение этой концепции?
public class demo {
public static void main(String a[]) {
B b = (B) new A(); // compiles with the cast,
// but runtime exception - java.lang.ClassCastException
}
}
class A {
public void draw() {
System.out.println("1");
}
public void draw1() {
System.out.println("2");
}
}
class B extends A {
public void draw() {
System.out.println("3");
}
public void draw2() {
System.out.println("4");
}
}
Ответы:
Даункинг допускается, когда есть вероятность того, что он преуспеет во время выполнения:
В некоторых случаях это не удастся:
Если во время выполнения
ClassCastException
произойдет сбой приведения (например, последнего), будет сгенерировано.В остальных случаях это будет работать:
Обратите внимание, что некоторые приведения будут запрещены во время компиляции, потому что они никогда не будут успешны вообще:
источник
Object o = new Object(); String s = (String) o;
У меня нормально работает ..: O как?Используя ваш пример, вы можете сделать:
источник
Я считаю, что это относится ко всем статически типизированным языкам:
Фактически приведение типа говорит: предположите, что это ссылка на класс приведения и используйте его как таковой. Теперь предположим, что o на самом деле является целым числом, предполагая, что это строка не имеет смысла и даст неожиданные результаты, поэтому необходимо выполнить проверку во время выполнения и исключение, чтобы уведомить среду выполнения о том, что что-то не так.
На практике вы можете написать код, работающий с более общим классом, но привести его к подклассу, если вы знаете, что это за подкласс, и вам нужно обращаться с ним как с таковым. Типичным примером является переопределение Object.equals (). Предположим, у нас есть класс для автомобиля:
источник
Мы все видим, что предоставленный вами код не будет работать во время выполнения. Это потому, что мы знаем, что выражение никогда не
new A()
может быть объектом типа .B
Но это не то, как это видит компилятор. К тому времени, когда компилятор проверяет, разрешено ли приведение, он просто видит это:
И, как показали другие, такого рода актеры совершенно законны. Выражение справа может очень хорошо оценить объект типа
B
. Компилятор видит этоA
иB
имеет отношение подтипа, так что с представлением «выражения» кода приведение может работать.Компилятор не рассматривает особый случай, когда он точно знает , какой тип объекта
expression_of_type_A
будет действительно иметь. Он просто видит статический тип какA
и считает, что динамический тип может бытьA
или любым потомкомA
, в том числеB
.источник
Я полагаю, что это потому, что у компилятора нет возможности узнать во время компиляции, будет ли приведение выполнено успешно или нет. Для вашего примера просто увидеть, что приведение не удастся, но в других случаях это не так ясно.
Например, представьте, что все типы B, C и D расширяют тип A, а затем метод
public A getSomeA()
возвращает экземпляр B, C или D в зависимости от случайно сгенерированного числа. Компилятор не может знать, какой именно тип времени выполнения будет возвращен этим методом, поэтому, если вы позднее приведете результаты кB
, нет способа узнать, будет ли приведение выполнено успешно (или не получится). Поэтому компилятор должен предполагать, что приведение завершится успешно.источник
@ Оригинальный постер - см. Встроенные комментарии.
источник
Downcast работает в том случае, когда мы имеем дело с объектом, находящимся на подъеме. Приведение к базовому типу:
Так что теперь эта
objValue
переменная всегда может быть уменьшена,int
потому что объект, который был приведенInteger
,но поскольку
objValue
это объект, он не может быть приведен,String
потому чтоint
не может быть приведенString
.источник
Даункастинг очень полезен в следующем фрагменте кода, которым я пользуюсь все время. Таким образом, доказательство того, что уныние является полезным.
Я храню строку в связанном списке. Когда я получаю элементы связанного списка, объекты возвращаются. Чтобы получить доступ к элементам в виде строк (или любых других объектов класса), мне помогает downcasting.
Java позволяет нам компилировать унылый код, доверяя нам, что мы поступаем неправильно. Тем не менее, если люди совершают ошибку, она ловится во время выполнения.
источник
void*
указателей в C ++. Это совсем не похоже на хорошую идею.Рассмотрим пример ниже
здесь мы создаем объект подкласса Bone и назначаем его ссылке на суперкласс AOne, и теперь ссылка на суперкласс не знает о методе method2 в подклассе, т.е. Bone во время компиляции. Поэтому нам нужно уменьшить эту ссылку суперкласса до ссылки на подкласс результирующая ссылка может знать о наличии методов в подклассе, т.е. Bone
источник
Чтобы выполнить downcasting в Java и избежать исключений во время выполнения, воспользуйтесь ссылкой на следующий код:
Здесь Animal - родительский класс, а Dog - дочерний класс.
instanceof - это ключевое слово, которое используется для проверки, содержит ли ссылочная переменная заданный тип ссылки на объект или нет.
источник
Унизительное преобразование объектов невозможно. Только
возможно
источник