gpt4 book ai didi

java - block 作用域变量

转载 作者:搜寻专家 更新时间:2023-10-30 19:54:33 26 4
gpt4 key购买 nike

这将编译

class X
{
public static void main(String args[])
{
{
int a = 2;
}
{
int a = 3;
}
}
}

这不会

class X
{
public static void main(String args[])
{

int a = 2;

{
int a = 3;
}
}
}

我希望两者都能编译(也许这是 C 的工作方式?)。为什么不能在 block 中声明一个与外部 block 中的变量同名的变量?

最佳答案

简短的回答是:因为这是 Java 语言在 JLS §6.4 中定义的方式.

你可能会从其他语言中使用这个所谓的variable shadowing被允许。然而,Java 语言的发明者认为这是他们不希望在他们的语言中出现的一个笨拙的特性:

This restriction helps to detect some otherwise very obscure bugs.

但是,正如作者在 JLS 的同一部分中所述,您会在 Java 的其他地方发现阴影:

A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well.

这意味着在实践中以下代码是合法的:

class A {
int x = 0;
void m() {
int x = 10; // Shadows this.x
}
}

正如作者所描述的,允许通过声明一个具有相同名称的方法局部变量来隐藏一个实例变量,因为有朝一日有人可能会扩展 A 的功能,而您可以如果隐藏是非法的,则不再编译类 B:

class B extends A {
void m() {
int x = 10; // Shadows A.this.x if A declares x
}
}

如果考虑像 C 这样允许阴影的语言,您会发现像这样的笨拙代码:

int x;
int main()
{
{
int x = 0;
{
extern int x;
x = 1;
}
printf("%d\n", x); // prints 0
}
printf("%d\n", x); // prints 1
return 0;
}

这个程序不是那么容易遵循,因此可能不会产生您期望的结果,这要归功于变量阴影。

关于java - block 作用域变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20499554/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com