java中模式变量的范围是如何解析的?

Bea*_*r64 1 java pattern-matching jls java-14

我正在研究java中的模式变量。在阅读JLS时,它提到了有关何时引入模式变量的几个条件。它提到——

该分析依赖于技术术语“introduced by”,其形式如下:

  • 当 true 时,模式变量表达式引入
  • 当 false 时,模式变量表达式引入
  • 模式变量语句引入

在 6.3.1 中提到了表达式中模式变量的范围,其中指出何时为&&||!?:等引入模式变量。

但我觉得解释很混乱,谁能详细说明一下&&,,||!

模式变量的示例 -

Object o = "a";

if(o instanceof String s) {
    System.out.println(s); 
}
Run Code Online (Sandbox Code Playgroud)

我困惑的地方——

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
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

我不明白它如何在编译时解析变量的范围。另外,为什么不在selse 块的范围内,为什么在pelse 块的范围内。&&我不明白模式变量作用域如何与,||和混合使用!


请给出简单和复杂的例子。请尝试用简单和困难的例子来解释它,这真的会很有帮助。

Ste*_*n C 5

让我们考虑一下:

if (!(o instanceof Integer s)) {
    System.out.println(s);
Run Code Online (Sandbox Code Playgroud)

它说:

什么时候oInteger它绑定到s.

如果o不是Integer,则打印s

直观上:当o不是 an时Integer,我们没有将其绑定到s,因此s没有意义。

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

JLS 中指定这一点的部分......很复杂。但我认为您不需要了解使用模式变量的所有复杂性。只需使用JLS 6.3中这两句话背后的直观含义即可:

“模式变量声明的范围(即由模式声明的局部变量)是在值与模式匹配成功后可能执行的程序部分。它是通过考虑程序点来确定的其中模式变量在以声明模式变量的模式开头的区域中肯定匹配。”

因此,在我们的简单示例中,System.out.println(s)如果成功,则不是将执行的程序的一部分(o instanceof Integer s)。意思!是当不成功时执行this的then分支。if(o instanceof Integer s)