Accessing a class with the exact same name
I have a tricky question and I'm not sure if it is even possible in Java. I'm in the following situation:
I got a class A that uses another class, let's call it B. Now, I'm trying to write a third class (and I don't call it C), I call it B again (to be sure which class 'B' I mean, I will call it B1 and B2 in the rest of this post, ok?). All three classes resides in three different JAR-files. So far, so good.
Normaly, class A finds class B(1) on the classpath and will use it. But now I'm putting the JAR-file that contains B(2) at the very beginning of the classpath, so class A will find this class instead of the old one. So my class B(2) can act like the old class B(1) (which is a library in reality, that I can't customize in any other way. that's why I am doing that...).
And here comes my problem: In my class B(2) I want to load the real class B(1) and use it. I can do this so far by using reflection. I can even invoke methods via reflection, but I can't cast an instance of the loaded class to B reference. Here is the exception:
java.lang.ClassCas开发者_JAVA百科tException: my.a.ClassB incompatible with my.a.ClassB
Has anybody an idea how I can use class B(1) in class B(2)? I am happy with any workarround...
Thanx, Thomas.
You can only do this through reflection.
As far as the runtime system is concerned, your two ClassB classes are complete separate entities and cannot be cast to each-other.
This sometimes happens in OSGi environments (which have complex classloader setups) or if you somehow manage to pass data between web application contexts.
If you want a common interface to call methods on both without reflection, then you need to create just that: a common interface (or parent class). And that interface needs to reside in a jar file that both these ClassB can see.
Example:
first jar: interface I
second jar: class B implements I
third jar: class B implements I
Now you have two versions of class B, but they can both be cast to I.
Needless to say, you should find a better solution to whatever problem you have here.
Maybe you can use CDI to @Inject
the desired class into class A. Doing so helps you to mock classes and provide alternatives. See also the @Alternative
annotation of CDI. Basically you are using the interface methods, the implementation behind it is chosen at runtime or injectione time, resp.
精彩评论