Como han dicho otros, no existe tal cosa como # define/# ifdef en Java. Pero con respecto a su problema de tener bibliotecas externas opcionales, que usaría, si está presente, y no las usaría, usar clases proxy podría ser una opción (si las interfaces de la biblioteca no son demasiado grandes).
Tuve que hacer esto una vez para las extensiones específicas de Mac OS X para AWT/Swing (se encuentran en com.apple.eawt. *). Las clases son, por supuesto, solo en la ruta de clase si la aplicación se ejecuta en Mac OS. Para poder usarlos pero aún permitir el uso de la misma aplicación en otras plataformas, escribí clases de proxy simples, que solo ofrecían los mismos métodos que las clases originales de EAWT. Internamente, los proxies usaron alguna reflexión para determinar si las clases reales estaban en la ruta de clases y pasarían por todas las llamadas a métodos. Al utilizar la clase java.lang.reflect.Proxy, puede incluso crear y pasar objetos de un tipo definido en la biblioteca externa, sin tenerlo disponible en tiempo de compilación.
Por ejemplo, el proxy para com.apple.eawt.ApplicationListener era la siguiente:
public class ApplicationListener {
private static Class<?> nativeClass;
static Class<?> getNativeClass() {
try {
if (ApplicationListener.nativeClass == null) {
ApplicationListener.nativeClass = Class.forName("com.apple.eawt.ApplicationListener");
}
return ApplicationListener.nativeClass;
} catch (ClassNotFoundException ex) {
throw new RuntimeException("This system does not support the Apple EAWT!", ex);
}
}
private Object nativeObject;
public ApplicationListener() {
Class<?> nativeClass = ApplicationListener.getNativeClass();
this.nativeObject = Proxy.newProxyInstance(nativeClass.getClassLoader(), new Class<?>[] {
nativeClass
}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
ApplicationEvent event = new ApplicationEvent(args[0]);
if (methodName.equals("handleReOpenApplication")) {
ApplicationListener.this.handleReOpenApplication(event);
} else if (methodName.equals("handleQuit")) {
ApplicationListener.this.handleQuit(event);
} else if (methodName.equals("handlePrintFile")) {
ApplicationListener.this.handlePrintFile(event);
} else if (methodName.equals("handlePreferences")) {
ApplicationListener.this.handlePreferences(event);
} else if (methodName.equals("handleOpenFile")) {
ApplicationListener.this.handleOpenFile(event);
} else if (methodName.equals("handleOpenApplication")) {
ApplicationListener.this.handleOpenApplication(event);
} else if (methodName.equals("handleAbout")) {
ApplicationListener.this.handleAbout(event);
}
return null;
}
});
}
Object getNativeObject() {
return this.nativeObject;
}
// followed by abstract definitions of all handle...(ApplicationEvent) methods
}
Todo esto sólo tiene sentido, si necesita sólo unas pocas clases de una biblioteca externa, ya que hay que hacer todo a través de la reflexión en tiempo de ejecución. Para bibliotecas más grandes, probablemente necesite alguna forma de automatizar la generación de los proxies. Pero entonces, si realmente dependes de una gran biblioteca externa, solo deberías requerirla en tiempo de compilación.
El comentario de Peter Lawrey: (Lo siento editar, es muy difícil código para poner en un comentario)
El ejemplo sigue es genérica por el método de modo que no es necesario conocer todos los métodos involucrados. También puede hacer esto genérico por clase, por lo que solo necesita una clase InvocationHandler codificada para cubrir todos los casos.
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
ApplicationEvent event = new ApplicationEvent(args[0]);
Method method = ApplicationListener.class.getMethod(methodName, ApplicationEvent.class);
return method.invoke(ApplicationListener.this, event);
}
No creo que esto sea lo que está buscando. Él no quiere constantes simbólicas, sino un equivalente a la compilación condicional. Sin saber java, no tengo ni idea, aunque ... – dmckee
¿qué pasa con la compilación condicional? ¿Cómo haces eso en Java? – Russell
El artículo que he vinculado discute esto. –