IntelliJ 显示 "always true" 提示但不显示 "always false" instanceof
IntelliJ show "always true" hint but not "always false" for 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 没有给我一个“[...] 是总是假的”提示。有谁知道为什么?
更新:已在 IDEA 2018.3 中修复。
(免责声明:IntelliJ IDEA 开发者在此,谁负责此功能)。
简短回答:因为它没有实现。
当我们在数据流分析中跟踪变量的实际类型时,我们使用 TypeConstraint class 描述的模型。它允许我们跟踪两种事实:1)如果变量实际类型是 instanceof something 和 2)如果变量实际类型不是 instanceof something。有了这些事实,我们可以推断在许多情况下总是 true/always false 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
表达式我们可以知道 [=12] 更精确的类型信息=] 是 exactly One
。这并不经常使用,因为在大多数情况下(变量是方法参数,变量从方法返回,变量从字段赋值,数组元素,强制转换表达式等)我们无法知道类型是精确类型还是子类型,所以目前的模型是完全令人满意的。我只能想象 exactly One
事实跟踪有用的两种情况:new
表达式(就像你的情况一样)和比较后 obj.getClass() == Xyz.class
.
我认为,这是一个可以合理实施的功能。这个我已经考虑过了,但是除了我还有人关心,所以我提交了an issue,所以你可以跟踪它。
所以,我使用 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 没有给我一个“[...] 是总是假的”提示。有谁知道为什么?
更新:已在 IDEA 2018.3 中修复。
(免责声明:IntelliJ IDEA 开发者在此,谁负责此功能)。
简短回答:因为它没有实现。
当我们在数据流分析中跟踪变量的实际类型时,我们使用 TypeConstraint class 描述的模型。它允许我们跟踪两种事实:1)如果变量实际类型是 instanceof something 和 2)如果变量实际类型不是 instanceof something。有了这些事实,我们可以推断在许多情况下总是 true/always false 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
表达式我们可以知道 [=12] 更精确的类型信息=] 是 exactly One
。这并不经常使用,因为在大多数情况下(变量是方法参数,变量从方法返回,变量从字段赋值,数组元素,强制转换表达式等)我们无法知道类型是精确类型还是子类型,所以目前的模型是完全令人满意的。我只能想象 exactly One
事实跟踪有用的两种情况:new
表达式(就像你的情况一样)和比较后 obj.getClass() == Xyz.class
.
我认为,这是一个可以合理实施的功能。这个我已经考虑过了,但是除了我还有人关心,所以我提交了an issue,所以你可以跟踪它。