gpt4 book ai didi

java - 使用 Java 8 lambda 表达式打印有关错误的调试信息

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

我想使用静态方法作为 setter helper 来捕获异常并打印有关失败操作的调试信息。我不想要异常详细信息。我想显示正在设置的属性,以便详细信息有助于快速调试问题。我正在使用 Java 8。

我应该如何提供或检测正在设置的属性?

我希望删除示例中的“name”字符串并得到相同的结果。

我知道我不能对已转换为 lambda 表达式然后转换为 BiConsumer 的提供的 setter 方法使用反射。

我知道了,但需要提供属性名称。

/** setter helper method **/
private static <E, V> void set(E o, BiConsumer<E, V> setter,
Supplier<V> valueSupplier, String propertyName) {
try {
setter.accept(o, valueSupplier.get());
} catch (RuntimeException e) {
throw new RuntimeException("Failed to set the value of " + propertyName, e);
}
}

例子:

    Person p = new Person();
Supplier<String> nameSupplier1 = () -> "MyName";
Supplier<String> nameSupplier2 = () -> { throw new RuntimeException(); };
set(p, Person::setName, nameSupplier1, "name");
System.out.println(p.getName()); // prints MyName
set(p, Person::setName, nameSupplier2, "name"); // throws exception with message Failed to set the value of name
System.out.println(p.getName()); // Does not execute

编辑:我知道反射对 lambda 没有帮助。我知道 AOP,我知道这也可以通过纯反射来实现,但我想知道是否有更好的方法来使用 Java 8 完成此操作,而 Java 7 不存在。在我看来应该如此。现在可以做一些事情,例如将一个 setter 方法传递给到另一个。

最佳答案

如果您希望方法引用作为唯一的输入,您可以使用以下技巧将它们调试为可打印的名称:

public static void main(String[] args) {
Person p = new Person();
Supplier<String> nameSupplier1 = () -> "MyName";
Supplier<String> nameSupplier2 = () -> { throw new RuntimeException(); };
set(p, Person::setName, nameSupplier1);
System.out.println(p.getName()); // prints MyName
set(p, Person::setName, nameSupplier2); // throws exception with message
System.out.println(p.getName()); // Does not execute
}

interface DebuggableBiConsumer<A, B> extends BiConsumer<A, B>, Serializable {}

private static <E, V> void set(
E o, DebuggableBiConsumer<E, V> setter, Supplier<V> valueSupplier) {
try {
setter.accept(o, valueSupplier.get());
} catch (RuntimeException e) {
throw new RuntimeException("Failed to set the value of "+name(setter), e);
}
}

private static String name(DebuggableBiConsumer<?, ?> setter) {
for (Class<?> cl = setter.getClass(); cl != null; cl = cl.getSuperclass()) {
try {
Method m = cl.getDeclaredMethod("writeReplace");
m.setAccessible(true);
Object replacement = m.invoke(setter);
if(!(replacement instanceof SerializedLambda))
break;// custom interface implementation
SerializedLambda l = (SerializedLambda) replacement;
return l.getImplClass() + "::" + l.getImplMethodName();
}
catch (NoSuchMethodException e) {}
catch (IllegalAccessException | InvocationTargetException e) {
break;
}
}
return "unknown property";
}

限制是它会打印不是很有用的 lambda 表达式方法引用(对包含 lambda 代码的合成方法的引用)和 "unknown property"用于接口(interface)的自定义实现。

关于java - 使用 Java 8 lambda 表达式打印有关错误的调试信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21860875/

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