2015-04-12 3 views
0

В Java tutorial on type erasure, похоже, не указаны конкретные правила вставки броска компилятором. Может кто-то пожалуйста, объясните конкретные правила, которые вызывают трансформацию подробно в учебнике (приводится ниже):Тип стирания Java: правила вставки литья?

public class Node<T> { 
    public T data; 

    public Node(T data) { this.data = data; } 

    public void setData(T data) { 
     System.out.println("Node.setData"); 
     this.data = data; 
    } 
} 
public class MyNode extends Node<Integer> { 
    public MyNode(Integer data) { super(data); } 

    public void setData(Integer data) { 
     System.out.println("MyNode.setData"); 
     super.setData(data); 
    } 
} 

MyNode mn = new MyNode(5); 
Node n = (MyNode)mn;   // A raw type - compiler throws an unchecked warning 
n.setData("Hello"); 
Integer x = (String)mn.data; // Causes a ClassCastException to be thrown. 

В частности, я задаюсь вопросом, какие правила вызывают вставки (MyNode) и (String). Когда вставлен литой и как выбран тип для броска?

+0

Компилятор не вставляет ролики. Вы, как программист, должны вставлять приведения в случае необходимости, а компилятор проверяет, правильны они или нет. –

+1

Это неправда, это добавит броски за кулисами. – Crazyjavahacking

ответ

0
  1. MyNode mn = new MyNode(5);

    • будет создавать экземпляр MyNode, который определяет общий тип T интерфейса Node, как Integer
    • литья: нет литья необходимо разработчиком, никаких слепков не добавлены компилятором
  2. Node n = (MyNode)mn;

    • это будет в основном сказать компилятор забыть о родовом типе T и использовать интерфейс Node полностью без дженериков, которые будут иметь следующие последствия: представить обобщенный тип T следует рассматривать как java.lang.Object
    • литье: литье не требуется разработчиком, отливки не добавлены компилятором
  3. n.setData("Hello");

    • позволит вам добавить любой вид акушера объект, поскольку T рассматривается как объект (String, Integer, массив, что-нибудь еще)
    • литье: нет литья необходимо застройщиком, ни слепков добавляют компилятором
  4. Integer x = mn.data;

    • nm.data должен возвращать Integer типа, как Integer определяется как общий аргумент типа T в MyNode класса
    • однако, потому что вы использовали исходные типы, позволяющие вам добавить String вместо этого, nm.data имеет String экземпляр
    • литье: не требуется литье разработчиком, однако компилятор добавит отливки для целых чисел за кулисами для вас и из-за несоответствия типов, вы получите ClassCastException
+0

Можете ли вы подробно рассказать о том, когда * вставляются листки? Я думаю, что я понимаю «почему», но я не могу понять, в каких обстоятельствах акты важны. – Kvass

+0

Добавлены объяснения кастинга. – Crazyjavahacking

0

The ClassCastException будет throw, когда вызов делается на

n.setData("Hello"); 

Это происходит потому, что компилятор строит методы моста, чтобы сохранить полиморфизм. Метод моста будет выглядеть следующим образом:

public void setData(Object data) { 
     setData((Integer)data); //the exception is thrown here 
    } 

поскольку экземпляр строки не может быть преобразован в IntegerClassCastException будет брошен.

Вы можете прочитать о методах моста here.