Java中的显式对象转换

时间:2016-03-04 17:14:22

标签: java intellij-idea casting

我对Java比较新,所以问题就在于此。为什么Java转换对象以及在转换对象时编译器究竟发生了什么。这是我的简单级别订单搜索代码。

void LevelOrder(Node root)
    {
       Queue<Node> Q = new LinkedList();
       Q.add(root);
       while(!Q.isEmpty()){
           Node p = Q.poll();
           System.out.print(p.data+ " ");
           if(p.left != null) Q.add(p.left);
           if(p.right != null) Q.add(p.right);
       }


    }

当我在黑客级别提供的基于Web的IDE上运行此代码时,它会编译,但会给我以下警告。

Note: Solution.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

当我通过将poll的行更改为

来投射节点对象时
Node p = (Node)Q.poll();

它仍然编译显示相同的警告。

然而,在我的IntelliJ IDE上,第一个代码甚至不会编译,只有第二个代码(使用显式强制转换)编译。

有人可以解释这里发生了什么。 除了解决错误之外,有人可以解释为什么一个编译器允许这行编译,而另一个编译器没有显式转换。

Node p = Q.poll();

3 个答案:

答案 0 :(得分:3)

new LinkedList();

这是一个raw-typed集合 - 编译器不知道其中包含哪些类型的元素(即使其中实际上没有没有)。

因此,当您尝试将其分配给只能包含Node类型元素的引用时:

Queue<Node> Q = new LinkedList();

然后编译器无法知道这是否安全。

修复很简单:告诉编译器元素的类型:

Queue<Node> Q = new LinkedList<Node>();

在Java 7 +中可以更简单:

Queue<Node> Q = new LinkedList<>();

在这种情况下,编译器将类型推断为<Node><>被称为&#34;钻石符号&#34 ;;它不能在所有情况下使用,但可以在这样的赋值上下文中使用。

答案 1 :(得分:1)

原因是这一行:

Queue<Node> Q = new LinkedList();

如果您将其更改为

Queue<Node> Q = new LinkedList<Node>();

警告消遣者。

在第一种情况下,您有一个Object列表,
在第二个Node列表中。

这在编译时主要是相关的。稍后在执行期间,所有集合都是Object类型。如果将其他类型的对象输入到列表中,则会在运行时获得ClassCastException。 (如果编译器无法检测到您添加了错误类型的对象)

从java 1.7开始,只需编写

即可
Queue<Node> Q = new LinkedList<>();

编译器现在足够聪明,知道你的意思是Node

答案 2 :(得分:1)

在声明如下链接列表后添加<>修复此行:

Queue<Node> Q = new LinkedList<>();

或者你也可以这样做:

Queue<Node> Q = new LinkedList<Node>();

请注意,可以使用JDK 7中的菱形运算符代替显式类型参数。所以我更喜欢第一种方式。