Java Name Hiding: The Hard Way

java, member-hiding, name-clash

Solution

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

- being side-effect free (a problem with instantiating `net.foo.X`),

- not requiring renaming of anything (so you can give the method in `B` the name you want it to have; that's why a `import static` won't work in your exact case),

- not requiring the introduction of delegate class (though that might be a good idea…), and

- not requiring the overhead or complexity of working with the reflection API.

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.

Problem

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.

Original source

Related problems