Java Name Hiding: The Hard Way

Solution 1:

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.

Solution 2:

Probably the simplest (not necessarily the easiest) way to manage this would be with a delegate class:

import net.foo.X;
class C {
    static void doSomething() {
         X.doSomething();
    }
}

and then ...

class B extends A {
    void doX(){
        C.doSomething();
    }
}

This is somewhat verbose, but very flexible - you can get it to behave any way you want; plus it works in much the same way both with static methods and instantiated objects

More about delegate objects here: http://en.wikipedia.org/wiki/Delegation_pattern

Solution 3:

You can use a static import:

import static net.foo.X.doSomething;

class B extends A {
    void doX(){
        doSomething();
    }
}

Watch out that B and A do not contain methods named doSomething

Solution 4:

The proper way of doing things would be the static import, but in the absolute worst case scenario, you COULD construct an instance of the class using reflection if you know its fully qualified name.

Java: newInstance of class that has no default constructor

And then invoke the method on the instance.

Or, just invoke the method itself with reflection: Invoking a static method using reflection

Class<?> clazz = Class.forName("net.foo.X");
Method method = clazz.getMethod("doSomething");
Object o = method.invoke(null);

Of course, these are obviously last resorts.

Solution 5:

Not really THE answer but you could create an instance of X and call the static method on it. That would be a way (dirty I admit) to call your method.

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