用java 8 lambdaexpression式打印错误信息

我想使用一个静态方法作为setter助手来捕获exception,并打印有关失败操作的debugging信息。 我不想只有例外的细节。 我想显示哪些属性正在设置,以便详细帮助快速debugging问题。 我正在使用Java 8。

我应该如何提供或检测设置的财产?

我希望在示例中删除“名称”string,并得到相同的结果。

我知道我不能使用所提供的setter方法的reflection来转换为lambdaexpression式,然后转换为BiConsumer。

我得到这个,但需要提供属性名称。

/** 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 

编辑:我知道reflection并没有帮助lambdas。 我知道AOP,我知道这也可以用纯粹的reflection,但我想知道是否有一个更好的方法来完成与Java 7不存在的Java 8这似乎应该对我来说。 现在可以做一些事情,比如传递一个setter方法到另一个方法

如果你期望方法引用是唯一的input,你可以使用下面的技巧将它们debugging到可打印的名字:

 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"; } 

限制是它将为lambdaexpression式(包含lambda代码的合成方法的引用)和接口的自定义实现的"unknown property"打印不太有用的方法引用。