泛型类型擦除和类型转换
Generics type erasure and type cast
我想查找异常原因,直到找到 "the right one",但看起来类型正在被删除,函数 returns 传递的异常导致 main 中的 ClassCastException。
这是我的代码:
public class Main {
public static void main(String[] args) {
Throwable e0 = new CertPathValidatorException("0");
Throwable e1 = new CertificateException(e0);
Throwable e2 = new CertificateException(e1);
Throwable e3 = new CertificateException(e2);
CertPathValidatorException cpve = Main.<CertPathValidatorException>getCauseOf(e3);
}
@Nullable
private static <Ex extends Exception> Ex getCauseOf(final Throwable e) {
Throwable cause = e;
while (true) {
try {
return (Ex) cause;
}
catch (ClassCastException cce) {
cause = cause.getCause();
}
}
}
}
有没有办法让这个函数保持通用,或者我应该放弃这个想法?
在这里使用泛型是危险的。 Java 在编译时解析泛型。在您的代码中,您需要在运行时进行解析。您可以通过将 class 作为参数传递给您的函数来实现。
private static <Ex extends Exception> Ex getCauseOf(final Class<Ex> typeResolve, final Throwable e) {
Throwable cause = e;
while (cause != null) {
if (typeResolve.isInstance(cause)) return (Ex) cause; // or typeResolve.cast(cause);
else cause = cause.getCause();
}
return null;
}
这样,您可以修改调用如下:
CertPathValidatorException cpve = Main.getCauseOf(CertPathValidatorException.class, e3);
我想查找异常原因,直到找到 "the right one",但看起来类型正在被删除,函数 returns 传递的异常导致 main 中的 ClassCastException。 这是我的代码:
public class Main {
public static void main(String[] args) {
Throwable e0 = new CertPathValidatorException("0");
Throwable e1 = new CertificateException(e0);
Throwable e2 = new CertificateException(e1);
Throwable e3 = new CertificateException(e2);
CertPathValidatorException cpve = Main.<CertPathValidatorException>getCauseOf(e3);
}
@Nullable
private static <Ex extends Exception> Ex getCauseOf(final Throwable e) {
Throwable cause = e;
while (true) {
try {
return (Ex) cause;
}
catch (ClassCastException cce) {
cause = cause.getCause();
}
}
}
}
有没有办法让这个函数保持通用,或者我应该放弃这个想法?
在这里使用泛型是危险的。 Java 在编译时解析泛型。在您的代码中,您需要在运行时进行解析。您可以通过将 class 作为参数传递给您的函数来实现。
private static <Ex extends Exception> Ex getCauseOf(final Class<Ex> typeResolve, final Throwable e) {
Throwable cause = e;
while (cause != null) {
if (typeResolve.isInstance(cause)) return (Ex) cause; // or typeResolve.cast(cause);
else cause = cause.getCause();
}
return null;
}
这样,您可以修改调用如下:
CertPathValidatorException cpve = Main.getCauseOf(CertPathValidatorException.class, e3);