静态内部类M
和静态成员M
[类C
]如何共享相同的名称?
以下代码生成“白色”作为输出:
public class Amazed{
public static void main(String[] args) {
System.out.println(B.M.W);
}
}
class B {
public static class M {
static String W = "Black";
}
static C M = new C();
}
class C {
String W = "White";
}
如何访问成员对象而不是静态类成员:W [“Black”]
如果我想访问静态类M中的成员怎么做?
答案 0 :(得分:2)
Chapter 6 of the Java Language Specification(特别是Section 6.5)详细说明了Java如何排序特定标识符在特定上下文中的含义。规则相当复杂,但粗略地说,Java有六个名称空间:
相同的标识符可用于每个名称空间中的实体。请注意,类型(类)名称和字段名称分开存在,这解释了为什么您的代码是合法的。
同一名称空间中的继承名称有时也可以被遮蔽或屏蔽。有时标识符不明确;然后它需要以某种方式进行限定(例如,使用包名称),否则编译器会抱怨。
代码混淆器使用它非常有利,最终可以在程序包a.a
中找到名为a
的程序包和一个名为a
的类(也可以识别它)作为a.a
)。更不用说像do
和for
这样的Java关键词在.class文件中是合法的名称(但在Java源代码中却不是)。它有助于使逆向工程变成真正的熊。
答案 1 :(得分:1)
变量掩盖了同名的类型。如果名称可以解释为变量或类型,则首选该变量。
你可以通过不给它们相同的名字来避免这种情况。
来自Java语言规范,section 6.4.2: Obscuring:
6.4.2。模糊
一个简单的名称可能出现在上下文中,它可能被解释为变量,类型或包的名称。在这些情况下,§6.5的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包。因此,有时可能无法通过其简单名称引用可见类型或包声明。我们说这样的声明是模糊不清的。
答案 2 :(得分:0)
在您可以实例化M
的特定情况下,您可以使用以非静态方式访问静态的事实:
public class Amazed{
@SuppressWarnings("static-access")
public static void main(String[] args) {
B.M val = new B.M();
System.out.println(val.W);
}
}
class B {
public static class M {
static String W = "Black";
}
static C M = new C();
}
class C {
String W = "White";
}
上面将打印出黑色'因为您通过B.M
的实例引用标识符来消除歧义。当然,这绝不是生产代码中的好主意,因为静态字段不应以非静态方式访问。同样,它要求您创建B.M
的实例。
答案 3 :(得分:0)
在每个人的帮助和小玩之后,我发现即使没有为内部类创建对象,我们也可以访问成员W“Black”。
只需使用此声明
M.W
但我无法弄清楚访问级别。 [因为它的公众?]即使没有公开它也有效。怎么样?