I have a problem with name hiding that is extremely hard to solve. Here is a simplified version that explains the problem:
There is a class: org.A
package org;
public class A{
public class X{...}
...
protected int net;
}
Then there is a class net.foo.X
package net.foo;
public class X{
public static void doSomething();
}
And now, here is the problematic class which inherits from A
and wants to call 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
}
}
As you see, this is not possible. I cannot use the simple name X
because it is hidden by an inherited type. I cannot use the fully qualified name net.foo.X
, because net
is hidden by an inherited field.
Only the class B
is in my code base; the classes net.foo.X
and org.A
are library classes, so I cannot alter them!
My only solution looks like this:
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! Is there no solution in which I can directly call X.doSomething()
from B.doSomething()
?
In a language that allows specifying the global namespace, e.g., global::
in C# or ::
in C++, I could simply prefix net
with this global prefix, but Java does not allow that.
You can cast a null
to the type and then invoke the method on that (which will work, since the target object isn't involved in invocation of static methods).
((net.foo.X) null).doSomething();
This has the benefits of
net.foo.X
),B
the name you want it to have; that's why a import static
won't work in your exact case),The downside is that this code is really horrible! For me, it generates a warning, and that's a good thing in general. But since it's working around a problem that is otherwise thoroughly impractical, adding a
@SuppressWarnings("static-access")
at an appropriate (minimal!) enclosing point will shut the compiler up.