If you only need to access the class C
through an interface which you know you will have access to, then it is simple enough:
MyInterface provider=null;
try{
Class myClass= Class.forName("sysPackage.C");
provider = (MyInterface)(myClass.newInstance());
}catch(Exception ex){
}
if(provide!=null){
//Use provider
}
If C
does not have an interface that can be used, then we can instead create a wrapper class S
that will be a member of the interface instead.
class S implements MyInterface{
static {
try {
Class.forName("sysPackage.C");
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void forceExceptionIfUnavailable() {}
//TODO: Methods that use C. Class C will only be used within this class
}
S
has a static block so that an exception is thrown during class resolution if C
is unavailable. Immediately after loading the class, we call forceExceptionIfUnavailable
to make sure that the static block is run immediately. If it doesn't crash, then we can use the methods in S
to indirectly use class C
.
Alternatively, we can use the method here:
Basically, you create a new package P
, with a public abstract class A
and a concrete subclass S
private to the package. A
has a static method getS
that returns an instance of S
or null
if an exception is thrown during instantiation. Each instance of S
has an instance of C
so it will fail to instantiate when C
is unavailable - otherwise it will succeed. This method seems to be a bit safer as S
(and hence all the C
APIs) are package private.