Если вам нужно получить доступ к классу 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) являются частными пакетами.
person
Casebash
schedule
15.03.2010