0

考虑官方帮助中的示例:

public class Node<T>{
    private 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");
        this.data=data;
    }
}
public class MyClass{
    public static void main(String[] args){
        Node n = new MyNode(5);
        n.setData(new Object());//ok
    }
}
  1. 是什么意思Node n= new MyNode(5);Node n是对原始类型的引用,但我将其描述Node<T>为泛型类。原始类型是否是所有Node通用类型的超类型?如果我们定义对原始类型的引用,那么泛型类型编译器在哪里不对类型进行检查,而是在哪里开始类型擦除?编译器默认匹配的语句是错误的,因为它不是.Node<T>TNode nNode<T>Node<T>TObjectNode<Object>Node<Integer>

  2. 编译器的类型参数是什么TNode<T>编译器是否T只考虑作为引用类型,但他不知道关于 的描述T

4

1 回答 1

2

1)

Node n= new MyNode(5);

您有一个指向 MyNode 对象(的子类Node<Integer>)的原始(未指定类型)节点引用。

原始类型 Node 是所有 T 的泛型类型 Node 的超类型吗?

节点不是超类(supertype)的Node<T>

如果我们定义对原始类型节点 n 的引用,那么Node<T>泛型类型编译器在哪里没有类型检查,而是在哪里开始类型擦除,这是真的Node<T>吗?

编译器只检查引用,如果你的引用是原始的,那么你可以添加任何你想要的类型。泛型被引入 Java 语言以在编译时提供更严格的类型检查并支持泛型编程。泛型是编译器唯一的问题,在编译期间类型被擦除(擦除)并且泛型不会产生运行时开销

默认情况下编译器将 T 匹配到 Object 的语句是错误的,因为Node<Object>它不是Node<Integer>.

您尚未为泛型类 Node 指定类型,这相当于Node<Object>. Node<Object>不是的超类,Node<Integer>也不是和的任何组合,Node<A>它们Node<B> 在运行时都是同一个类!

2) Type T 是你在使用时指定的。在 Node 类定义中,T 只是一个占位符,因此您可以在下一行使用相同的类型来指定数据类型。将 T inNode<T>视为一个参数,可以在类的其他地方使用。(您可以将 T 替换为您想要的任何变量,但是使用 T 是惯例,除非它是我们使用 E 的集合)。

考虑以下...

public class MyClass extends ArrayList<Integer> {
    public static void main(String[] args) {
        ArrayList<Integer> a = new MyClass();
        a.add(new Integer(5));
        ArrayList b = a;
        b.add(new String("abc"));

        for (Integer i : a) {
            //System.out.print(i);
        }
    }
}

这将编译得很好,因为 a 是一个 ArrayList。

请记住,泛型仅适用于编译器,因此一旦编译它们就不再影响代码。我们可以使用原始类型的引用 b 为同一对象起别名,从而允许我们将其他对象添加到列表中(例如字符串)。

现在,当我们尝试将 a 作为整数的 ArrayList 循环时,我们在运行时惊讶地发现它包含一个字符串,完全可以添加(因为所有 ArrayList 都ArrayList<Object>在运行时)但不允许转换为整数.

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at MyClass.main(MyClass.java:11)
于 2013-09-30T08:31:25.097 回答