【发布时间】:2014-08-25 16:04:59
【问题描述】:
我有一个非常难以解决的名称隐藏问题。这是解释问题的简化版本:
有一个类: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.X 和 org.A 类是库类,所以我无法更改它们!
我唯一的解决方案如下所示:
我可以调用另一个类,然后调用X.doSomething();但是这个类只会因为名字冲突而存在,看起来很乱!有没有可以直接从B.doSomething()调用X.doSomething()的解决方案?
在允许指定全局命名空间的语言中,例如 C# 中的 global:: 或 C++ 中的 ::,我可以简单地为 net 加上这个全局前缀,但 Java 不允许这样做。
【问题讨论】:
-
一些快速修复可能是这样的:
public void help(net.foo.X x) { x.doSomething(); }并使用help(null);调用 -
@Absurd-Mind:嗯,通过不存在的对象调用静态方法似乎比我的解决方案更混乱 :)。我什至会收到编译器警告。但确实,这将是除我之外的另一个 hacky 解决方案。
-
@JamesB:这会实例化错误的 X!
net.foo.X有方法,不是org.A.X! -
你有从
A继承吗?正如你所发现的那样,继承可以如此令人讨厌…… -
I could call another class that in turn calls X.doSomething(); but this class would only exist because of the name clash, which seems very messy+1 表示清洁代码的态度。但对我来说,这似乎是你应该权衡的情况。只需执行此操作,然后就您为什么必须这样做(可能带有此问题的链接)提出一个很好的长评论。
标签: java name-clash member-hiding