java中模式变量的作用域是如何解析的?

How is the scope of pattern variables resolved in java?

我正在查看 java 中的模式变量。在阅读 JLS 时,它提到了关于何时引入模式变量的几个条件。 它提到 -

The analysis relies on the technical term "introduced by", which has the following form:

  • a pattern variable is introduced by an expression when true
  • a pattern variable is introduced by an expression when false
  • a pattern variable is introduced by a statement

在 6.3.1 中它提到了表达式中模式变量的作用域,其中说明了何时为 &&||!?: 引入模式变量等

不过我觉得解释的很乱,谁能详细说一下&&||!

模式变量示例-

Object o = "a";

if(o instanceof String s) {
    System.out.println(s); 
}

我困惑的地方-

class foo {
    String s, n, p, m;

    void method() {
        Object o = "s";
        if (!(o instanceof Integer s) && o instanceof Integer n) {
            System.out.println(s + " " + n);  // n in scope but s is not in scope
        } else {
            System.out.println(s + " " + n); // neither s nor n is in scope
        }
        System.out.println(s + " " + n); // neither s nor n is in scope (Instance variables s and n over here)

        if (!(o instanceof String p) || o instanceof Integer m) {
            System.out.println(p + " " + m); // neither p nor m is in scope (Instance variables p and m over here)
        } else {
            System.out.println(p + " " + m); // p in scope but m is not in scope
        }

    }

}

我不明白它是如何在编译时确定变量的范围的。另外,为什么 s 不在 else 块的范围内,为什么 p 在 else 块的范围内。我不明白模式变量范围如何与 &&||!.

混合使用
请举出简单和复杂的例子。 请尝试用简单和困难的例子来解释它,真的很有帮助。

让我们考虑一下:

if (!(o instanceof Integer s)) {
    System.out.println(s);

它说:

When o is an Integer bind it to s.

Then if o is not an Integer, print s.

直觉上:当 o 不是 Integer 时,我们 没有 将它绑定到 s,所以 s没有意义。

如果你看一个更复杂的例子,它很可能在其根源上有这种逻辑。

指定此内容的 JLS 部分……很复杂。但我不认为您需要了解所有这些复杂性才能使用模式变量。就用JLS 6.3:

这两句话背后的直观意义

"The scope of a pattern variable declaration (that is, a local variable declared by a pattern) is the part of the program that might be executed after the matching of a value against the pattern has succeeded. It is determined by considering the program points where the pattern variable is definitely matched in a region beginning with the pattern that declares the pattern variable."

所以在我们的简单示例中,System.out.println(s) 不是 (o instanceof Integer s) 成功时将要执行的程序的一部分。 !表示then这个if的分支在(o instanceof Integer s)不成功的时候执行