gpt4 book ai didi

Java:获取 lambda 的泛型类型

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:11:27 24 4
gpt4 key购买 nike

首先,我应该说我能够获得泛型类型的实例或匿名内部类。

下面是代码示例,寻找catch block :

public static interface MyInterface<E extends Throwable>{
void call() throws E;
}


public static <E extends Throwable> void method(MyInterface<E> lambda) throws E {
try {
lambda.call();
} catch(Throwable ex) {
// Pseudo code
Class<?> T = ((ParameterizedType)ex.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
if ( T.isInstance(ex) ) {
throw ex;
} else {
...
}
}
}

public static void throwsException() throws Exception {
throw new Exception();
}

这行不通:

method(() -> {
throwsException();
});

但是这样做:

method(new MyInterface<Exception>() {
@Override
public void call() throws Exception {
throwsException();
}
});

但是随着 Lambda 的引入,我不能再强制执行这个了!

还应注意,这现在可能会破坏与早于 < 8 的库的向后兼容性,并且反射(reflect)了此信息。

我已经研究过这个主题,似乎只有获取方法参数的可能解决方法,但这是关于抛出部分的,所以不会起作用。

注意:我已经看过这个帖子了: Reflection type inference on Java 8 Lambdas

最佳答案

你可以简单地写

public static interface MyInterface<E extends Throwable>{
void call() throws E;
}

public static <E extends Throwable> void method(MyInterface<E> lambda) throws E {
try {
lambda.call();
}
catch(Throwable ex) {
throw ex;
}
}

不处理反射。自 MyInterface<E>.call()保证抛出可分配给 E 的类型或仅未经检查的异常,很明显捕获到 ex必须是可分配给 E 的类型之一或未经检查的异常,因此可以安全地重新抛出。

这从 Java 7 开始有效。


相比之下,如果您的方法执行其他可能引发异常的操作,则不保证与 E 兼容。 ,你应该明确地声明它们而不是做反射魔法。否则你有一个方法以一种奇怪的方式改变它的行为,因为它取决于参数是一个特定的异常类型被简单地抛出还是以不同的方式处理(包装或你的后备行为是什么)。

请注意,您的反射魔法无论如何都被破坏了。考虑这个简单的例子:

class Foo<E extends Throwable> implements MyInterface<E> {
public void call() throws E {
}
}

直接实例化此类时,无法通过反射在运行时获取实际类型参数。这与通过 lambda 表达式创建的实现的行为完全相同。

关于Java:获取 lambda 的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27550314/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com