gex*_*ide 96 java name-clash member-hiding
我有一个名称隐藏问题,这是一个非常难以解决的问题.这是一个解释问题的简化版本:
有一节课: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Run Code Online (Sandbox Code Playgroud)
然后是一堂课 net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
Run Code Online (Sandbox Code Playgroud)
而现在,这是一个有问题的类,它继承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
}
}
Run Code Online (Sandbox Code Playgroud)
如你所见,这是不可能的.我不能使用简单名称,X因为它被继承的类型隐藏.我无法使用完全限定名称net.foo.X,因为net它被继承的字段隐藏.
只有类B在我的代码库中; 类net.foo.X和org.A库类,所以我不能改变它们!
我唯一的解决方案是这样的:我可以调用另一个反过来调用的类X.doSomething(); 但是这个类只会因为名字冲突而存在,这看起来非常混乱!有没有解决方案,我可以直接调用X.doSomething()从B.doSomething()?
在允许指定全局命名空间的语言中,例如,global::在C#或::C++中,我可以简单地net使用此全局前缀作为前缀,但Java不允许这样做.
Don*_*ows 84
您可以将a null转换为该类型,然后在该方法上调用该方法(这将起作用,因为目标对象不涉及静态方法的调用).
((net.foo.X) null).doSomething();
Run Code Online (Sandbox Code Playgroud)
这有好处
net.foo.X),B你想要的名称给出方法;这就是为什么import static在你的确切情况下不起作用的原因),缺点是这段代码非常可怕!对我来说,它产生一个警告,这是一件好事.但是因为它解决了一个原本不切实际的问题,所以添加一个
@SuppressWarnings("static-access")
Run Code Online (Sandbox Code Playgroud)
在适当的(最小!)封闭点将关闭编译器.
blg*_*lgt 38
管理这个的最简单(不一定是最简单)的方法可能是委托类:
import net.foo.X;
class C {
static void doSomething() {
X.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
然后 ...
class B extends A {
void doX(){
C.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
这有点冗长,但非常灵活 - 你可以让它以你想要的任何方式行事; 加上它与static方法和实例化对象的工作方式大致相同
有关委托对象的更多信息,请访问:http://en.wikipedia.org/wiki/Delegation_pattern
Abs*_*ind 37
您可以使用静态导入:
import static net.foo.X.doSomething;
class B extends A {
void doX(){
doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
注意B并且A不包含命名的方法doSomething
Epi*_*rce 16
正确的做法是静态导入,但在绝对最坏的情况下,如果你知道它的完全限定名,你可以使用反射构造一个类的实例.
然后在实例上调用该方法.
或者,只需使用反射调用方法本身: 使用反射调用静态方法
Class<?> clazz = Class.forName("net.foo.X");
Method method = clazz.getMethod("doSomething");
Object o = method.invoke(null);
Run Code Online (Sandbox Code Playgroud)
当然,这些显然是最后的度假胜地.
不是答案,但你可以创建一个X实例并在其上调用静态方法.这将是一种方式(脏我承认)来调用你的方法.
(new net.foo.X()).doSomething();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4483 次 |
| 最近记录: |