【问题标题】:static inner class and static member of a class shares SAME NAME? [duplicate]静态内部类和类的静态成员共享同名? [复制]
【发布时间】:2013-07-27 01:34:58
【问题描述】:

静态内部类M 和静态成员M [类C] 怎么可以同名?

以下代码生成“White”作为输出:

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 中的成员,该怎么做?

【问题讨论】:

  • 我喜欢meth 的方法让你无处可去。不过,很长的 while 循环可能更合适。
  • @thatidiotguy:或者一些递归直到它爆栈的东西。
  • 感谢 BMT。但我不明白模糊和重新分类的规范......有人可以帮助我吗?
  • @Dineshkumar 访问字段的方式有优先级。
  • 如果您感到惊讶,请阅读此stackoverflow.com/questions/17690135/…

标签: java static-methods static-members


【解决方案1】:

在您可以实例化 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 的实例。

【讨论】:

    【解决方案2】:

    变量掩盖了同名的类型。如果名称可以解释为变量或类型,则首选变量。

    你可以通过不给他们相同的名字来避免这种情况。

    来自 Java 语言规范,section 6.4.2: Obscuring

    6.4.2。遮蔽

    一个简单的名称可能出现在它可能被解释为变量、类型或包的名称的上下文中。在这些情况下,§6.5 的规则指定将优先选择变量而不是类型,并且将优先选择类型而不是包。因此,有时可能无法通过其简单名称来引用可见类型或包声明。我们说这样的声明是模糊的。

    【讨论】:

    • 怎么选的?优先顺序是什么?
    • 1) 变量 2) 类型 3) 包名
    • 这里的 Type 是否意味着除了类以外的任何东西?
    • 表示任何类型,包括类和接口。原始类型是关键字,因此不能将它们用作变量名。
    【解决方案3】:

    Chapter 6 of the Java Language Specification(尤其是Section 6.5)阐明了 Java 如何在特定上下文中整理出特定标识符的含义的可怕细节。规则相当复杂,但粗略地说,Java 有六个命名空间:

    • 包名称
    • 类型名称
    • 字段(变量)名称
    • 方法名称
    • 局部变量名(包括参数)
    • 标签

    相同的标识符可用于每个名称空间中的实体。请注意,类型(类)名称和字段名称是分开存在的,这就解释了为什么您的代码是合法的。

    同一名称空间中的继承名称有时也可以被隐藏或屏蔽。有时标识符是模棱两可的;然后需要以某种方式对其进行限定(例如,使用包名),否则编译器会报错。

    代码混淆器利用这一点非常有利,以至于您最终可以在包a 中得到一个名为a.a 的包和一个名为a 的类(也将被标识为a.a)。更不用说像dofor 这样的Java 关键字是.class 文件中的合法名称(但不是Java 源代码)。它有助于使逆向工程成为真正的熊。

    【讨论】:

      【解决方案4】:

      经过大家的帮助和小玩,我发现即使没有为内部类创建对象,我们也可以访问成员 W“Black”。

      只需使用此语句

      M.W
      

      但我无法确定访问级别。 [因为它是公开的?] 即使没有公开它也有效。怎么样?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-04
        • 1970-01-01
        • 1970-01-01
        • 2016-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多