Java 名称隐藏 : The Hard Way

标签 java name-clash member-hiding

我有一个非常难以解决的名称隐藏问题。这是解释问题的简化版本:

有一个类:org.A

package org;
public class A{
     public class X{...}
     ...
     protected int net;
}

然后有一个类net.foo.X

package net.foo;
public class X{
     public static void doSomething();
}

现在,这是继承自 A 并想调用 net.foo.X.doSomething()

的有问题的类
package com.bar;
class B extends A {

    public void doSomething(){
        net.foo.X.doSomething(); // doesn't work; package net is hidden by inherited field
        X.doSomething(); // doesn't work; type net.foo.X is hidden by inherited X
    }
}

如您所见,这是不可能的。我不能使用简单的名称 X 因为它被继承的类型隐藏。我不能使用完全限定名称 net.foo.X,因为 net 被继承的字段隐藏。

只有类 B 在我的代码库中; net.foo.Xorg.A 类是库类,所以我无法更改它们!

我唯一的解决方案如下所示: 我可以调用另一个类,然后调用 X.doSomething();但是这个类只会因为名字冲突而存在,看起来很乱!有没有我可以直接从 B.doSomething() 调用 X.doSomething() 的解决方案?

在允许指定全局命名空间的语言中,例如,C# 中的 global:: 或 C++ 中的 ::,我可以简单地为 net 带有这个全局前缀,但 Java 不允许这样做。

最佳答案

您可以将 null 强制转换为该类型,然后对其调用方法(这将起作用,因为目标对象不参与静态方法的调用)。

((net.foo.X) null).doSomething();

这有以下好处

  • 没有副作用(实例化 net.foo.X 的问题),
  • 不需要重命名任何东西(因此您可以为 B 中的方法指定您想要的名称;这就是为什么 import static 在您的确切的情况),
  • 不需要引入委托(delegate)类(尽管这可能是个好主意……),并且
  • 不需要使用反射 API 的开销或复杂性。

缺点是这段代码真的很糟糕!对我来说,它会产生警告,总的来说这是一件好事。但由于它正在解决一个完全不切实际的问题,因此添加一个

@SuppressWarnings("static-access")

在适当的(最小的!)封闭点将关闭编译器。

关于Java 名称隐藏 : The Hard Way,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24572214/

相关文章:

java - 在子类中隐藏方法

java - 关于在 Java 中隐藏/隐藏成员变量的问题

java - 调用 setOnClickListener 时传递参数?

java - 为什么 Jeromq 的 .term() 会无限阻塞,即使我调用了 .close() 来关闭所有套接字?

java - 如何改进 Java 泛型通配符签名

扩展时 Java 泛型名称冲突

c++ - 隐藏重载的虚函数

java - Java中的单例设计模式和单例对象有什么区别?

c++ - 命名空间与两个大型库发生冲突

java - 由于相同的删除而导致名称冲突