sir*_*lot 43 java lambda closures java-8
我糊涂了.我认为Java8将从石器时代开始出现并开始支持lambda/closures.但是当我尝试:
public static void main(String[] args) {
int number = 5;
ObjectCallback callback = () -> {
return (number = number + 1);
};
Object result = callback.Callback();
System.out.println(result);
}
Run Code Online (Sandbox Code Playgroud)
它说number should be effectively final.那是呃,不是我认为的封闭.这听起来像是通过值而不是通过引用来复制环境.
奖金问题!
android会支持Java-8功能吗?
Ste*_*n C 40
为什么哦,为什么,Java.为什么哦为什么.
您需要与相关的Oracle Java团队成员进行长时间(私人)讨论,以获得真正的答案.(如果他们愿意和你说话......)
但我怀疑它是向后兼容性和项目资源约束的组合.事实上,从务实的角度来看,目前的做法"足够好".
将过程上下文实现为第一类对象(即闭包)要求某些局部变量的生命周期超出声明方法调用的返回.这意味着你不能只把它们放在堆栈上.相反,您最终会遇到一些局部变量必须是堆对象的字段的情况.这意味着您需要一种新的隐藏类或对JVM体系结构的基本更改.
虽然在技术上可以实现这种方式,但Java语言不是"绿色领域"语言.改变支持"真正关闭"的性质需要很难:
Oracle和第三方实现者需要花费大量精力来更新所有工具链.(而且我们不只是谈论编译器.有调试器,分析器,混淆器,字节码工程框架,持久性框架......)
然后存在这些变化中的一些会影响数百万现有已部署的Java应用程序的向后兼容性的风险.
以某种方式利用JVM 对其他语言等有潜在影响.例如,Android依赖于JVM架构/字节码文件作为其Davlik工具链的"输入语言".Python,Ruby和各种函数语言都有语言实现,这些语言为JVM平台生成代码.
简而言之,Java中的"真正关闭"对于所有相关人员来说都是一个非常可怕的命题."决赛关闭"黑客是一种务实的妥协,确实有效,这在实践中已经足够好了.
最后,总是有可能final在将来的版本中删除限制.(虽然我不会屏住呼吸......)
android会支持Java-8功能吗?
除非有人具有可靠的内部知识,否则这是不可能回答的.如果他们这样做,他们会疯狂地在这里透露它.谷歌尚未宣布支持Java 8.
但好消息是KitKat和相应版本的Android Studio或Eclipse ADT现在支持Java 7语法扩展.
new*_*cct 13
你必须陈述你的"封闭"的定义.
对我来说,"闭包"是某种东西(一种可以以某种方式运行的函数或对象或其他东西,比如有方法)从其封闭范围捕获("封闭")局部变量,并且可以使用该变量在其代码中,即使函数或对象的方法在以后运行,包括封闭范围不再存在时.在不同的语言中,可以通过值或通过引用或两者来捕获变量.
通过这个定义,Java匿名类(自Java 1.1以来一直存在)是闭包,因为它们可以从其封闭范围引用局部变量.
Java 8中的Lambdas基本上是匿名类的一个特例(即,一个匿名类,它实现了一个只有一个方法的接口(一个"功能接口"),并且没有实例变量,并且没有引用它自己(使用)this明确地或隐含地)).任何lambda都可以重写为等效的匿名类表达式.所以上面所说的也适用于lambdas.
那是呃,不是我认为的封闭.
嗯,你先生,对"封闭"有一个混乱的定义.
Vol*_*ibt 11
I think the final restriction has technical reasons. A lambda expression simply takes the value from the surrounding method context because the reference lives on the stack and will not survive the finishing of the method.
If you put the context's value into a reference, you can build a "real" closure:
import java.util.function.Supplier;
public class CreatingAClosure {
public static void main(String[] args) {
Supplier<Supplier<String>> mutterfunktion = () -> {
int container[] = {0};
return () -> {
container[0]++;
return "Ich esse " + container[0] + " Kuchen.";
};
};
Supplier<String> essen = mutterfunktion.get();
System.out.println(essen.get());
System.out.println(essen.get());
System.out.println(essen.get());
}
}
Run Code Online (Sandbox Code Playgroud)
Ausgabe:
Ich esse 1 Kuchen.
Ich esse 2 Kuchen.
Ich esse 3 Kuchen.
Run Code Online (Sandbox Code Playgroud)
Instead of an array you can take any suitable instance of any object, because it lives on the heap and only the reference to this instance is kept (final) in the lambda expression.
In this case the value of container is enclosed into mutterfunktion. Every call to mutterfunktion creates a new referenced instance.
The value is not accessible from outside the function (which was very hard to build in Java 7 and before). Because of lambda expressions are implemented as method references, there are no inner classes involved in this example.
You could also define container in the method's context an you will be able to do changes outside the lambda:
public static void main(String[] args) {
int container[] = {0};
Supplier<String> essen = () -> {
container[0]++;
return "Ich esse " + container[0] + " Kuchen.";
};
System.out.println(essen.get());
System.out.println(essen.get());
container[0]++;
System.out.println(essen.get());
}
Run Code Online (Sandbox Code Playgroud)
Ausgabe:
Ich esse 1 Kuchen.
Ich esse 2 Kuchen.
Ich esse 4 Kuchen.
Run Code Online (Sandbox Code Playgroud)
So the answer to your question will be "yes".
| 归档时间: |
|
| 查看次数: |
16852 次 |
| 最近记录: |