Reputation: 59268
I know there are no macros in Java, but is there a workaround to do something like this:
#ifdef _FOO_FLAG_
import com.x.y.z.Foo;
#else
import com.a.b.c.Foo;
#endif
Both Foo
classes have the same methods. One of them is from a 3rd party library. I want to be able to switch to default library easily by changing a single line of code. Is this possible?
EDIT:
Both classes are out of my control(one of them is from SQLCipher for Android project, other one is from Android SDK). I need this because SQLCipher library doesn't work on SAMSUNG phones at the moment.
Upvotes: 11
Views: 16307
Reputation: 147
My answer linking to how to use the C-preprocessor was converted to a comment by someone who seemed to miss the fact that using that would precisely allow you write:
#ifdef _FOO_FLAG_
import com.x.y.z.Foo;
#else
import com.a.b.c.Foo;
#endif
Look for the hidden comment under the question.
Anyway since all you need is versioning, here's a simpler to use preprocessor that should work with the android setup: http://prebop.sourceforge.net/
If what you really want is two builds, then wrapping classes or writing code to choose at run time is a waste of effort and unnecessary complexity.
Upvotes: 0
Reputation: 12620
You can also detect the presence of certain classes at runtime using Class.forName(). This allows you to deploy the same build to different environments/devices.
Upvotes: 0
Reputation: 8276
The way this sort of thing is typically handled in Java is with a dependency injection framework such as Spring or Guice. In Spring, for example, you'd have two different "application contexts" to switch between the two implementations, but the rest of the Java code would be identical.
The only catch is that your com.a.b.c.Foo
and com.x.y.z.Foo
do need to implement a common interface -- it's not good enough for them to simply have the same methods, even with a nice dependency injection framework.
Upvotes: 3
Reputation: 308159
No, there is no commonly used pre-processor in Java (although you could use the C preprocessor on your Java code, but I'd discourage it, as it would be very unusual and would break most tools that handle your code). Such selections are usually done at runtime rather than compile-time in Java.
The usual Java-way for this is to have both classes implement the same interface and refer to them via the interface only:
IFoo myFoo;
if (FOO_FLAG) { // possibly a public static final boolean
myFoo = new com.x.y.z.Foo();
} else {
myFoo = new com.a.b.c.Foo();
}
If this is not possible (for example if at least one of the Foo
classes is not under your control), then you can achieve the same effect by an abstract FooWrapper
class (or interface) with two different implementations (XYZFooWrapper
, ABCFooWrapper
).
Upvotes: 20