Если вам нужен доступ к классу C
только через интерфейс, к которому, как вы знаете, у вас будет доступ, он достаточно прост:
MyInterface provider=null;
try{
Class myClass= Class.forName("sysPackage.C");
provider = (MyInterface)(myClass.newInstance());
}catch(Exception ex){
}
if(provide!=null){
//Use provider
}
Если C
не имеет интерфейса, который можно использовать, мы можем вместо этого создать класс-оболочку S
, который будет вместо этого членом интерфейса.
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
имеет статический блок, поэтому при разрешении класса выдается исключение, если C
недоступен. Сразу после загрузки класса мы вызываем forceExceptionIfUnavailable
, чтобы убедиться, что статический блок запускается немедленно. Если не произойдет сбой, мы можем использовать методы из S
, чтобы косвенно использовать класс C
.
В качестве альтернативы мы можем использовать метод здесь :
По сути, вы создаете новый пакет P
с открытым абстрактным классом A
и конкретным подклассом S
, приватным для пакета. A
имеет статический метод getS
, который возвращает экземпляр S
или null
, если во время создания создается исключение. Каждый экземпляр S
имеет экземпляр C
, поэтому он не будет создан, когда C
недоступен - в противном случае он будет успешным. Этот метод кажется более безопасным, поскольку S
(и, следовательно, все C
API) являются частными пакетами.