我想弄清楚Python lambdas.lambda是现实生活中应该被遗忘的"有趣"语言项目之一吗?
我确信有一些可能需要它的边缘情况,但考虑到它的模糊性,它在未来版本中重新定义的可能性(我基于它的各种定义的假设)和降低的编码清晰度 - 应该是要避免吗?
这让我想起C类型的溢出(缓冲区溢出) - 指向顶部变量并重载以设置其他字段值.感觉就像是一种技术表演,但维护编码器的噩梦.
由于Java8最近已经发布,并且它的全新lambda表达式看起来非常酷,我想知道这是否意味着我们习以为常的Anonymous类的消亡.
我一直在研究这个问题,并找到了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如Collection的sort方法,它用于获取Comparator的Anonymous实例来执行排序:
Collections.sort(personList, new Comparator<Person>(){
public int compare(Person p1, Person p2){
return p1.firstName.compareTo(p2.firstName);
}
});
Run Code Online (Sandbox Code Playgroud)
现在可以使用Lambdas完成:
Collections.sort(personList, (Person p1, Person p2) -> p1.firstName.compareTo(p2.firstName));
Run Code Online (Sandbox Code Playgroud)
而且看起来非常简洁.所以我的问题是,有没有理由继续在Java8中使用这些类而不是Lambdas?
编辑
同样的问题,但在相反的方向,使用Lambdas而不是匿名类有什么好处,因为Lambdas只能用于单个方法接口,这个新功能只是在少数情况下使用的快捷方式还是真的有用?
这个问题现在已经超过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) (这很难搜索,因为结果都是关于"方法参考")
我想获得一个Methodlambda表达式的实例,以便与基于遗留反射的API一起使用.应该包含clousure,因此调用thatMethod.invoke(null, ...)应该与调用lambda具有相同的效果.
我看过MethodHandles.Lookup,但它似乎只与逆向变换有关.但我想这种bind方法可能有助于包括clousure?
编辑:
说我有lambda experssion:
Function<String, String> sayHello = name -> "Hello, " + name;
Run Code Online (Sandbox Code Playgroud)
我有一个具有API 的遗留框架(SpEL)
registerFunction(String name, Method method)
Run Code Online (Sandbox Code Playgroud)
这将调用Method没有this参数的给定(即假定方法是静态的).所以我需要得到一个Method包含lambda逻辑+ clousure数据的特殊实例.
Java 8具有名为Type annotations(JSR 308)的功能.我想将它用于简单的Object to Object映射器框架.我想像这样定义注释@ExpectedType
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExpectedType {
public Class<?> value();
}
Run Code Online (Sandbox Code Playgroud)
然后在我的代码中使用它,如下所示:
public class SomeServiceImpl() {
public @ExpectedType(ObjectA_DTO.class) IObjectA doSomething(@ExpectedType(ObjectA_Entity.class) IObjectA obj) {
return (ObjectA_Entity) obj; // it's correct
}
}
Run Code Online (Sandbox Code Playgroud)
IObjectA是一个由类ObjectA_DTO和ObjectA_Entity.实现的接口.我想用这种方式服务:
// it's correct
assert someService.doSomething(new ObjectA_DTO()).getClass() == ObjectA_DTO.class;
Run Code Online (Sandbox Code Playgroud)
我想更改SomeServiceImpl方法的调用以使用Object mapper.它可以通过使用JSR 269或AOP 生成的代码来实现.
问题是我编写了简单的注释处理器,它根本不处理类型注释.简单注释处理器的来源如下所示:
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SimpleAnnotationsProcessor extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Messager messager = …Run Code Online (Sandbox Code Playgroud) 而不是像这样使用匿名类
register(new EventListener() {
@Override
public void apply(Event e) {
// do your work
}
});
Run Code Online (Sandbox Code Playgroud)
使用java 8我可以使用lambda表达式:
register(e -> (// do your work));
Run Code Online (Sandbox Code Playgroud)
但是如果我的界面中的方法被注释呢?
interface EventListener {
@Annotation
void apply;
}
Run Code Online (Sandbox Code Playgroud)
是否可以注释lambda表达式?(具体来说,我想使用带有lambda表达式的Guava的EventBus.register()方法)
lambda ×5
java ×4
java-8 ×4
annotations ×1
closures ×1
function ×1
java-9 ×1
python ×1
reflection ×1