因此,我使用IntelliJ IDEA在Java中进行编程,并且我尝试使用关键字instanceof
,并且我的代码最终看起来像这样:
public class Main {
public static void main(String args[])
{
One one = new One();
One two = new Two();
if (one instanceof Two)
{
System.out.println(one);
}
if (two instanceof Two)
{
System.out.println(one);
}
}
}
class One { }
class Two extends One { }
IntelliJ在two instanceof Two
行给我一个提示“ [...]始终为真”,但是对于one instanceof Two
,IntelliJ没有给我一个“ [[...]始终为假” ”提示。有人知道为什么吗?
答案 0 :(得分:5)
更新:已在IDEA 2018.3。中修复。
(免责声明:IntelliJ IDEA开发人员在这里,负责此功能)。
简短的回答:因为尚未实施。
当我们在数据流分析中跟踪变量的实际类型时,我们使用TypeConstraint类描述的模型。它允许我们跟踪两种事实:1)如果变量实际类型不是某事的instanceof; 2)如果变量实际类型不是某事的instanceof。有了这些事实,我们就可以在许多情况下推断出永远为真/总是为假的实例,例如:
void test(Object foo) {
if (foo instanceof String) {
if (foo instanceof Integer) {
// always false: "instanceof String" fact is not compatible
// with "instanceof Integer"
}
}
}
或
void test(Object foo) {
if (!(foo instanceof Number)) {
if (foo instanceof Integer) {
// always false: "not instanceof Number" fact is not compatible
// with "instanceof Integer"
}
}
}
但是,对于您的情况,此模型还不够。我们需要扩展它以跟踪变量的确切类型。在您的代码中,我们跟踪one
是instanceof One
(与instanceof Two
事实兼容),尽管从new
表达式中我们可以知道{{1 }}是one
。这通常不可用,因为在大多数情况下(变量是方法参数,变量是从方法返回的,变量是从字段,数组元素,转换表达式等分配的),我们无法知道类型是精确类型还是子类型,因此当前模型是完全令人满意的。我可以想象只有两种情况,exactly One
事实跟踪很有用:exactly One
表达式(如您的情况)和经过比较之后的new
。
我认为,这是实施的合理功能。我已经考虑过这一点,但是除了我以外的其他人也很在意,我提交了an issue,以便您进行跟踪。