我目前有多个类,即 FacadeA
...FacadeZ
,它们扩展了 FacadeBase
。 FacadeBase
应该有(某种通用方法?),即 checkFacade
,它会抛出异常 FacadeAException
...FacadeZException
扩展了FacadeException
。
这就是我目前所能得到的。我被通用部分困住了(或者任何能解决我问题的东西)。
是的,我知道我无法像我的示例中编写的那样实例化泛型。
public abstract class FacadeBase {
public void checkFacade(final String facadeId) throws Facade<A...Z>Exception {
if (!isFacadeAvailable(facadeId)) {
throw new Facade<A...Z>Exception(facadeId);
}
}
...
}
public class FacadeA extends FacadeBase {
public void doSomethingWithFacadeA(final String facadeId) throws FacadeAException {
checkFacade(facadeId));
...
}
}
public class FacadeAException extends FacadeException {
private FacadeAException(final String message) {
super(message);
}
}
public abstract class FacadeException extends Exception {
private FacadeException(final String message) {
super(message);
}
}
最佳答案
您可以使用泛型,但这还不够,因为您需要在运行时实例化特定类型。
一般来说,你有两种方法:
- 反射方式
- 声明式方式
1)反射方式并不简单。 Java 并没有提供您执行此操作所需的全部功能。您可以从 Spring 中获得灵感或使用库来做到这一点。
org.springframework.core.GenericTypeResolver
应该特别对你有帮助。
您可以使用 static Class<?> resolveTypeArgument(Class<?> clazz, Class<?> genericIfc)
方法:
Resolve the single type argument of the given generic interface against the given target class which is assumed to implement the generic interface and possibly declare a concrete type for its type variable.
如:
public abstract class FacadeBase<T extends FacadeException> {
private final Class<T> genericClazz;
public FacadeBase () {
this.genericClazz = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), FacadeBase.class);
}
}
现在您可以使用genericClazz.newInstance()
实例化泛型类。或更好Constructor.newInstance()
。
2) 声明式方式更简单,但需要一些样板代码。
使您的抽象类成为指定异常类型的泛型类,并提供一个存储要引发的异常的构造函数。
例如:
public abstract class FacadeBase<T extends FacadeException> {
private Supplier<T> suppException;
public FacadeBase(Supplier<T> suppException) {
this.suppException = suppException;
}
public void checkFacadeAvailability(final String facadeId) throws T {
if (!isFacadeAvailable(facadeId)) {
throw suppException.get();
}
}
}
子类应该通过其供应商调用 super 构造函数:
public class FacadeA extends FacadeBase<FacadeExceptionA>{
public FacadeA(Supplier<FacadeExceptionA> suppException) {
super(suppException);
}
}
作为替代方案,您可以替换 Supplier
通过Class
参数但总体思路是一样的。
关于java - 从泛型返回异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51950949/