Подтвердить что ты не робот

Правила Java для кастинга

Когда какой-либо объект может быть перенесен в другой объект? Кастованный объект должен быть подтипом другого объекта? Я пытаюсь выяснить правила...

Изменить: я понял, что я вообще не объяснял свою проблему: в основном я бросаю объект в тип интерфейса. Однако во время выполнения я получаю java.lang.ClassCastException. Что должно произойти с моим объектом, чтобы я мог применить его к этому интерфейсу? Нужно ли это реализовать?

Спасибо

4b9b3361

Ответ 1

В Java существует два типа кастинг-ссылок:

  • Downcasting: если у вас есть ссылка переменная, относящаяся к подтипу объекта, вы можете присвоить его эталонная переменная подтипа. Вы должны сделать явное приведение, чтобы сделать это, и в результате вы можете доступ к элементам подтипа с эта новая ссылочная переменная.

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

Да, вам нужно реализовать интерфейс прямо или косвенно, чтобы включить привязку ссылки на объект класса к типу интерфейса.

Ответ 2

Это будет работать:

class Foo implements Runnable {
    public void run() {}
}

Foo foo = new Foo();
System.out.println((Runnable) foo);

Но это не будет:

class Bar {
    public void run() {}
}

Bar bar = new Bar();
System.out.println((Runnable) bar);

Поскольку Bar имеет метод run(), который может реализовать Runnable.run(), Bar не объявляется для реализации Runnable, поэтому его нельзя отнести к Runnable.

Java требует, чтобы вы объявляли реализованные интерфейсы по имени. У него нет duck typing, в отличие от некоторых других языков, таких как Python и Go

Ответ 3

Там есть интуитивный способ мышления об этом - вы не меняете объект с помощью броска, вы делаете только то, что уже было бы разрешено, если бы этот тип был известен - inotherwords, вы можете использовать только тип, который ваш объект уже есть. Поэтому просто посмотрите "вверх" на цепочку объектов, чтобы узнать, какие виды применяются к вашему объекту.

Таким образом, вы можете использовать интерфейс только в том случае, если он определен где-то выше в цепочке (например, если ваш родитель классов реализует его и т.д. и т.д.). Он должен быть явным - по вашему вопросу это звучит так, как будто вы можете подумать, что если вы реализуете метод "void foo()", тогда вы должны быть способны передать в интерфейс, который определяет метод "void foo()" - это иногда описывается как "duck typing" (если он ошеломляет, как утка, это утка), но это не так, как работает java.

Ответ 4

Предположим, мы хотим, чтобы объект d был привязан к A,

A a = (C) d;

Так что внутренне 3 правила были проверены компилятором и JVM. Компилятор проверяет первые 2 правила во время компиляции, а JVM проверяет последнее одно правило во время выполнения.

Правило 1 (Проверка времени компиляции):

Тип 'd' и C должны иметь какое-либо отношение (дочерний элемент к родительскому или родительскому к ребенку или тому же времени). Если нет отношений, мы получим ошибка компиляции (неконвертируемые типы).

Правило 2 (Проверка времени компиляции):

'C' должен быть того же типа или производного типа (подкласс) слова 'A' в противном случае мы получим ошибку компиляции (несовместимые типы).

Правило 3 (исключение времени выполнения):

Тип объекта времени выполнения 'd' должен быть таким же или иметь тип 'C' в противном случае мы получим исключение во время выполнения (ClassCastException Исключение).

Найдите следующие примеры, чтобы получить больше идей,

String s = new String("hello"); StringBuffer sb = (StringBuffer)s;  // Compile error : Invertible types because there is no relationship between.

Object o = new String("hello"); StringBuffer sb = (String)o;       // Compile error : Incompatible types because String is not child class of StringBuffer.

Object o = new String("hello"); StringBuffer sb = (StringBuffer)o; // Runtime Exception : ClassCastException because 'o' is string type and trying to cast into StingBuffer and there is no relationship between String and StringBuffer.

Ответ 5

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

EDIT:

Да, объект, который вы пытаетесь выполнить, должен будет реализовать интерфейс, чтобы вы могли его успешно выполнить.

Ответ 6

Если:

interface MyInterface{}

class MyClass implements MyInterface{}

Тогда

MyClass m = new MyClass();
MyInterface i = (MyInterface)m;

возможно.