IntelliJ显示instanceof的“始终为true”提示,但不显示“始终为false”

时间:2018-07-07 16:55:26

标签: java oop intellij-idea instanceof

因此,我使用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没有给我一个“ [[...]始终为假” ”提示。有人知道为什么吗?

1 个答案:

答案 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"
    }
  }
}

但是,对于您的情况,此模型还不够。我们需要扩展它以跟踪变量的确切类型。在您的代码中,我们跟踪oneinstanceof One(与instanceof Two事实兼容),尽管从new表达式中我们可以知道{{1 }}是one。这通常不可用,因为在大多数情况下(变量是方法参数,变量是从方法返回的,变量是从字段,数组元素,转换表达式等分配的),我们无法知道类型是精确类型还是子类型,因此当前模型是完全令人满意的。我可以想象只有两种情况,exactly One事实跟踪很有用:exactly One表达式(如您的情况)和经过比较之后的new

我认为,这是实施的合理功能。我已经考虑过这一点,但是除了我以外的其他人也很在意,我提交了an issue,以便您进行跟踪。