2015-04-14 3 views
1
public class { 
    main() { 
     // What is the different implications of these 2 down casts 

     Superclass tRefVar = new SubClass(); 

     // Down cast example 1 
     SubClass aVar = (SubClass) tRefVar; 

     // Down cast example 2 
     ((SubClass) tRefVar).someMethodInSubClass(); 
    } 
} 

Последствия, мудрый, каковы различия между примером 1 литья и примером 2?Разница между двумя типами downcasting

+2

Это то же самое.Второй пример - просто вызвать метод непосредственно после литья объекта, хранящегося в переменной –

+0

Если вы вызываете метод на aVar, вы получите тот же результат ... Если вам не нужен aVar для других операций, вы можете использовать второй пример. –

ответ

0

Кастинг ничем не отличается. В примере # 1 используется временная локальная переменная, а в примере # 2 - нет.

Разница здесь точно такая же, как, например,

int i = 0; 

int j = i * 2; // uses a temporary local 
result = j + 1; // 

result = (i * 2) + 1; // does not use a temporary local 
0

Они идентичны, вы используете

SubClass aVar = (SubClass) tRefVar 

Если вы хотите использовать более чем один раз aVar

+1

Или вы используете его, если вы просто не хотите какого-то огромного сложного и эзотерического выражения. – Radiodef

1

Там нет практически никакой разницы. В первом примере создается новая локальная переменная, а во втором - нет. Вот и все.

Чтобы заглянуть под капот немного и проверить, что, давайте рассмотрим этот простой класс с двумя методами, которые делают по существу то, что вы делаете в вашем примере:

public class Downcasts { 
    public int stringLength1(Object o) { 
    String s = (String) o; 
    return s.length(); 
    } 

    public int stringLength2(Object o) { 
    return ((String) o).length(); 
    } 
} 

Байткод для этих методов (которые вы можете увидеть javap -c Downcasts) являются:

public int stringLength1(java.lang.Object); 
    Code: 
    0: aload_1 
    1: checkcast  #2     // class java/lang/String 
    4: astore_2 
    5: aload_2 
    6: invokevirtual #3     // Method java/lang/String.length:()I 
    9: ireturn 

public int stringLength2(java.lang.Object); 
    Code: 
    0: aload_1 
    1: checkcast  #2     // class java/lang/String 
    4: invokevirtual #3     // Method java/lang/String.length:()I 
    7: ireturn 

Первый метод делает эти вещи:

  • String s = (String) o:
    • грузы o в стек
    • проверяет, что это строка
    • магазинов, в регистр 2
  • return s.length():
    • грузов регистр 2 в стек (это один мы только что сохранили)
    • вызывает String::length (виртуальная функция) на нем
    • возвращает результат

Второй метод делает:

  • return ((String) o).length():
    • нагрузки o в стек
    • проверяет, что это строка
    • вызывает String::length (виртуальная функция ции) на нем
    • возвращает результат
+0

спасибо, что помогло мне понять это больше. На самом деле, я думаю, мое основное замешательство в том, что он делает. он используется только для переопределения методов? – Bryan

+1

Нет, это только для методов, которые не существуют в суперклассе. В моем примере нет метода 'Object :: length', поэтому' o.length() 'не будет компилироваться вообще. Вы должны сказать компилятору: «Эта вещь, которую вы только знаете, - это объект, ну, на самом деле это String» - и это именно то, что делает литье. Фактически, это _all_, что делает кастинг - он вообще не изменяет объект или не превращает его в строку String, что иногда является путаницей. Это как если бы я сказал, что у меня есть машина, а потом сказал: «О, кстати, это двухдверный переворот». Это второе заявление не изменило автомобиль вообще. – yshavit

Смежные вопросы