Java 8是否支持闭包?
我很困惑。 我认为Java8将从石器时代出现并开始支持lambdas / closure。 但是当我尝试:
public static void main(String[] args) {
int number = 5;
ObjectCallback callback = () -> {
return (number = number + 1);
};
Object result = callback.Callback();
System.out.println(result);
}
它说这个number should be effectively final
。 那是呃,不是我想的封闭。 这听起来像是在按照价值而不是参照来复制环境。
奖金问题!
Android会支持Java-8功能吗?
为什么哦,为什么,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语法扩展。
你将不得不声明你的“封闭”的定义。
对我来说,一个“闭包”是一个东西(一个函数或对象或其他东西,可以以某种方式运行,例如拥有方法)从其封闭范围捕获(“关闭”)局部变量,并且可以使用该变量在其代码中,即使稍后运行函数或对象的方法,包括当封闭范围不再存在时。 在不同的语言中,可以通过值或参考或两者来捕获变量。
通过这个定义,Java匿名类(自Java 1.1以来一直存在)是闭包,因为它们可以从其封闭范围引用局部变量。
Java 8中的Lambdas基本上是一个匿名类的特例(即一个匿名类,它只用一个方法实现一个接口(一个“功能接口”),它没有实例变量,并且不引用它自己(使用this
明确或隐含))。 任何lambda都可以重写成一个等效的匿名类表达式。 所以上面说的也适用于lambda。
那是呃,不是我想的封闭。
那么,先生,你有一个“封闭”的定义。
我认为final
限制有技术上的原因。 lambda表达式只是从周围的方法上下文中获取值,因为引用位于堆栈上,并且不会在该方法结束后继续存在。
如果将上下文的值放入引用中,则可以构建“真实”闭包:
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());
}
}
Ausgabe:
Ich esse 1 Kuchen.
Ich esse 2 Kuchen.
Ich esse 3 Kuchen.
您可以使用任何合适的任何对象实例,而不是数组,因为它位于堆上,只有对该实例的引用保留在(最终)lambda表达式中。
在这种情况下, container
的值被包含在mutterfunktion
。 每次调用mutterfunktion
都会创建一个新的引用实例。
该值不能从函数外部访问(这在Java 7以及之前很难构建)。 由于lambda表达式是作为方法引用实现的,因此在此示例中没有涉及内部类。
你也可以在方法的上下文中定义container
,你可以在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());
}
Ausgabe:
Ich esse 1 Kuchen.
Ich esse 2 Kuchen.
Ich esse 4 Kuchen.
所以你的问题的答案将是“是”。
链接地址: http://www.djcxy.com/p/51283.html