Java 爪哇语;“关闭”;本地类与匿名类的比较
我已经研究了使用匿名类和本地类实现闭包的区别。我试图找出两者之间的所有差异,以便我知道哪种方法在哪种情况下更好 如果我错了,请纠正我:Java 爪哇语;“关闭”;本地类与匿名类的比较,java,closures,Java,Closures,我已经研究了使用匿名类和本地类实现闭包的区别。我试图找出两者之间的所有差异,以便我知道哪种方法在哪种情况下更好 如果我错了,请纠正我: 匿名类在每次创建新实例时都会创建一个类实例和对象实例 每次创建新实例时,本地类仅创建一个对象实例 因此,是否有一个时间或地点我应该使用匿名类而不是本地类 编辑:这两者似乎没有真正的区别,只是取决于样式和是否要重用该类 为了澄清我的意思,这里有一个我所说的例子: public class ClosureExample { interface Function
- 匿名类在每次创建新实例时都会创建一个类实例和对象实例
- 每次创建新实例时,本地类仅创建一个对象实例
public class ClosureExample {
interface Function {
void func(int value);
}
public static void main(final String[] args) {
final Function local1 = localClassClosure("Local1");
final Function local2 = localClassClosure("Local2");
final Function anonymous1 = anonymousClassClosure("Annonymous1");
final Function anonymous2 = anonymousClassClosure("Annonymous2");
for (int i = 0; i < 3; i++) {
local1.func(i);
local2.func(i);
anonymous1.func(i);
anonymous2.func(i);
}
}
private static Function localClassClosure(final String text) {
// Local class name is irrelevant in this example
class _ implements Function {
@Override public void func(final int value) {
System.out.println(text + ":" + value);
}
}
return new _();
}
private static Function anonymousClassClosure(final String text) {
return new Function() {
@Override public void func(final int value) {
System.out.println(text + ":" + value);
}
};
}
}
公共类closure示例{
接口函数{
void func(int值);
}
公共静态void main(最终字符串[]args){
最终函数local1=localClassClosure(“local1”);
最终函数local2=localClassClosure(“local2”);
最终函数anonymous1=anonymousClassClosure(“Annonymous1”);
最终函数anonymous2=anonymousClassClosure(“Annonymous2”);
对于(int i=0;i<3;i++){
local1.func(i);
local2.func(i);
匿名1.func(i);
匿名2.func(i);
}
}
私有静态函数localClassClosure(最终字符串文本){
//在本例中,本地类名是不相关的
类uu实现函数{
@重写公共void func(最终整数值){
System.out.println(text+“:”+值);
}
}
返回新的;
}
私有静态函数AnonymousClassClose(最终字符串文本){
返回新函数(){
@重写公共void func(最终整数值){
System.out.println(text+“:”+值);
}
};
}
}
希望有人能详细解释这种细微的差别,以及在什么情况下应该使用哪种方法。我很确定没有什么东西像对象实例,只有类实例。 因此,是的,为本地和匿名类型创建了一个对象。。 然而,不同之处在于,您不能重用匿名类(除非通过在方法中使用匿名类的方式——这种方式可以工作,但实际上不可维护),因此,当您所做的任何事情都是一次性的时,您可以使用匿名类。例如,使用事件侦听器 不过,我更喜欢命名类型而不是匿名类型 编辑: 你会发现我在这里很有用
(define inc (lambda (a) (lambda () (+ 1 a))))
(display ((inc 5)))
函数(lambda()(+1A))实际上会在每次匿名调用时重新创建,如((inc 5))。这就是匿名类背后的概念
与之相反:
(define inc (lambda (a) (+ 1 a)))
(display (inc 5))
其中,(lambda(a)(+1a))将在编译时存储在内存中,对(inc 5)的调用将只引用它。这就是本地类背后的概念。这激起了我的兴趣,我打开JD-GUI查看反编译类。编译后的两个匿名内部类之间实际上没有任何区别: 本地类:
class ClosureExample$1t implements ClosureExample.Function{
ClosureExample$1t(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
匿名类:
class ClosureExample$1 implements ClosureExample.Function{
ClosureExample$1(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
这两种方法都是实现匿名内部类的有效方法,它们似乎做了完全相同的事情
编辑:我将uu类重命名为t只是关于这一点的注释: 因此,是否有一个时间或地点我应该使用匿名类而不是本地类 如果需要在组件内快速设置事件侦听器[例如
keystener
],可以执行以下操作:
addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent ke){ ... }
// further implementation here
});
尽管它根本不可重用。为什么下划线是类名?你说的类实例和对象实例是什么意思?我指的是类装入器装入JVM的类。请注意,Java 8之前的“闭包”在这个问题中讨论的不是通常公认意义上的真正闭包。不同之处在于,封闭范围内的变量都必须是
final
。这允许通过将这些变量的卷影副本作为隐藏变量添加到内部/匿名类来模拟闭包行为。我已经意识到我的误解在哪里,没有实际的区别,我在某个地方读到,每次创建匿名类实例时都会创建一个新类。事实并非如此。该类只创建一次。编译器正在生成一个类,您不知道该类的名称。它可能类似于“RandomClassABlah”,直到我打印出正在创建的类名,我才意识到:ClosureExample$1_uuSureExample$1_uSureExample$1 ClosureExample$1我一直希望第二个匿名类是ClosureExample$2@Jyro117你让我想起了我的问题。请参阅我的更新。因此,在初始化之后,这两种方法之间没有任何区别?几乎。。因为据我记忆所及,java实际上在运行时创建类文件,即使是匿名类。Java并不是真正的函数式语言。在函数式语言中,这两种情况之间的区别是一个基本概念。啊,没有想到在反编译后查看类。是的,很有趣,其实没有区别!