Java 由于类型检查或三元运算符导致的编译错误?

Java 由于类型检查或三元运算符导致的编译错误?,java,Java,最近,我在下面的代码中遇到一个编译错误: import org.eclipse.swt.widgets.TreeItem; Object parent; // can only be a Tree or a TreeItem ... TreeItem item = new TreeItem((parent instanceof TreeItem) ? (TreeItem) parent : (Tree) parent, SWT.NONE); 编译器说:“构造函数TreeItem(Wid

最近,我在下面的代码中遇到一个编译错误:

import org.eclipse.swt.widgets.TreeItem;
Object parent; // can only be a Tree or a TreeItem    
...
TreeItem item = new TreeItem((parent instanceof TreeItem) ? (TreeItem) parent : (Tree) parent, SWT.NONE);
编译器说:“构造函数TreeItem(Widget,int)未定义”

然后我用另一个代码进行了尝试:

Object x = new Integer(1);

Test t = new Test((x instanceof String) ? (String) x : (Integer) x);

class Test{
    public Test(String s){}
    public Test(Integer i){}
}
并得到另一个错误:“构造函数测试(Object&Serializable&Comparable)未定义”

所以我不得不使用传统的if-else结构。你知道为什么编译器会这样吗?

描述了三元运算符

否则,第二个和第三个操作数的类型为S1和S2 分别地设T1为应用装箱的结果类型 转换为S1,并将T2作为应用 装箱转换为S2

条件表达式的类型是应用的结果 捕获转换()到lub(T1,T2)()

基本上,您可以将三元运算符视为一种方法:它只能有一个“返回类型”。由于
String
Integer
是两个不同的对象,它将查找公共超类和由这两个对象实现的所有接口,并从中创建一个返回类型。(
String
Integer
都实现了
Serializable
Comparable
并扩展了
Object
,因此您得到了
Object&Serializable&Comparable

描述了三元运算符

否则,第二个和第三个操作数的类型为S1和S2 分别地设T1为应用装箱的结果类型 转换为S1,并将T2作为应用 装箱转换为S2

条件表达式的类型是应用的结果 捕获转换()到lub(T1,T2)()


基本上,您可以将三元运算符视为一种方法:它只能有一个“返回类型”。由于
String
Integer
是两个不同的对象,它将查找公共超类和由这两个对象实现的所有接口,并从中创建一个返回类型。(
String
Integer
都实现了
Serializable
Comparable
并扩展了
Object
,因此得到了
Object&Serializable&Comparable

原因很简单:三元运算符的结果是静态类型。 在进行此类类型转换时,将返回的类型是两种可能结果中使用的类型的共同祖先。在第一个示例中,小部件是TreeItem和Tree的共同祖先,在第二个示例中,String和Integer的共同祖先是Object。
因此,当您将这样一个操作的结果用于一个新操作时,您需要一个通用类型的构造函数。

原因很简单:三元运算符结果是一个静态类型。 在进行此类类型转换时,将返回的类型是两种可能结果中使用的类型的共同祖先。在第一个示例中,小部件是TreeItem和Tree的共同祖先,在第二个示例中,String和Integer的共同祖先是Object。
因此,当您将这样一个操作的结果用于一个新操作时,您需要一个用于该公共类型的构造函数。

似乎我们正在讨论这个类。请注意,构造函数接受
Tree
TreeItem

现在,您正试图使用
instanceof
将该
对象强制转换为正确的类型。到目前为止还不错(不过设计有点争议)。不幸的是,三元运算符表达式类型必须在编译时解析。与此方法相比,
TreeItem
Tree
最具体的通用超类是
Widget

public Widget smartCast(Object parent) {
    if(parent instanceof TreeItem) {
        return (TreeItem)parent;
    } else {
        return (Tree)parent;
    }
}

smartCast
不能有除
小部件
之外的任何其他返回类型,就像您的三元运算符一样。

似乎我们正在讨论这个类。请注意,构造函数接受
Tree
TreeItem

现在,您正试图使用
instanceof
将该
对象强制转换为正确的类型。到目前为止还不错(不过设计有点争议)。不幸的是,三元运算符表达式类型必须在编译时解析。与此方法相比,
TreeItem
Tree
最具体的通用超类是
Widget

public Widget smartCast(Object parent) {
    if(parent instanceof TreeItem) {
        return (TreeItem)parent;
    } else {
        return (Tree)parent;
    }
}

smartCast
不能有除
Widget
之外的任何其他返回类型,就像您的三元运算符一样。

在创建对象时,java需要知道在编译时要使用哪个特定构造函数

构造函数测试(Object&Serializable&Comparable)之所以会出现这种奇怪的错误,是因为Integer和String都是从这3个测试(Object,Serializable,Comparable)继承的。所以在编译时,如果你有一个构造函数,它接受了其中的任何一个,Java就会知道你想要使用它

树和树也是如此。他们共同的父it部件。因此,它需要一个可以同时接受这两项的构造函数


它不能在运行时为一个新语句在两个不同的构造函数之间进行选择

在创建对象时,java需要知道在编译时要使用哪个特定的构造函数

构造函数测试(Object&Serializable&Comparable)之所以会出现这种奇怪的错误,是因为Integer和String都是从这3个测试(Object,Serializable,Comparable)继承的。所以在编译时,如果你有一个构造函数,它接受了其中的任何一个,Java就会知道你想要使用它

树和树也是如此。他们共同的父it部件。因此,它需要一个可以同时接受这两项的构造函数


它不能在运行时为一个新语句在两个不同的构造函数之间进行选择

请发布
TreeItem
的代码。我认为第二个代码示例表明它与特定类无关。我认为这是JAVA编译器的一般行为,它是新的