请看下面的代码:
Method methodInfo = MyClass.class.getMethod("myMethod");
Run Code Online (Sandbox Code Playgroud)
这可行,但方法名称作为字符串传递,因此即使myMethod不存在,这也将编译.
另一方面,Java 8引入了方法引用功能.它在编译时检查.可以使用此功能获取方法信息吗?
printMethodName(MyClass::myMethod);
Run Code Online (Sandbox Code Playgroud)
完整示例:
@FunctionalInterface
private interface Action {
void invoke();
}
private static class MyClass {
public static void myMethod() {
}
}
private static void printMethodName(Action action) {
}
public static void main(String[] args) throws NoSuchMethodException {
// This works, but method name is passed as a string, so this will compile
// even if myMethod does not exist
Method methodInfo = MyClass.class.getMethod("myMethod");
// Here we pass reference to a method. It …Run Code Online (Sandbox Code Playgroud) 这个问题现在已经超过3年了,并且专门针对Java 8,接受的答案也引用了Java SE 8最终规范.
如果在Java 9中有关于这个问题的内容会发生变化,我会感兴趣:有没有办法注释类似于注释相应匿名类的lambda表达式?
例:
注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface MyTypeAnnotation {
public String value();
}
Run Code Online (Sandbox Code Playgroud)
匿名类的工作注释:
Consumer<String> consumer = new @MyTypeAnnotation("Hello ") Consumer<String>() {
@Override
public void accept(String str) {
System.out.println(str);
}
};
Run Code Online (Sandbox Code Playgroud)
注释lamba表达式,目前在Java 8中不起作用:
Consumer<String> myAnnotatedConsumer = @MyTypeAnnotation("Hello") (p -> System.out.println(p));
Run Code Online (Sandbox Code Playgroud) 是否可以将方法引用(例如SomeClass::someMethod)转换为MethodHandle实例?我想要编译时检查的好处(确保存在类和方法)以及使用MethodHandleAPI 内省方法的能力.
用例:当且仅当请求未被特定方法触发时(以避免无限递归),我才需要执行代码.我想要一个编译时检查以确保类/方法存在但运行时检查以将调用者与方法进行比较.
所以回顾一下:是否可以将方法引用转换为MethodHandle?
我想使用静态方法作为setter helper来捕获异常并打印有关失败操作的调试信息.我不希望只有例外细节.我想显示正在设置的属性,以便详细帮助快速调试问题.我正在使用Java 8.
我应该如何提供或检测所设置的财产?
我希望删除示例中的"名称"字符串并获得相同的结果.
我知道我不能对提供的提供的setter方法使用反射,该方法转换为lambda表达式然后转换为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);
}
}
Run Code Online (Sandbox Code Playgroud)
例:
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 …Run Code Online (Sandbox Code Playgroud) java ×4
java-8 ×3
lambda ×3
reflection ×2
annotations ×1
debugging ×1
java-9 ×1
methodhandle ×1