我对内部类和lambda表达式有些困惑,我试图问一个问题,但随后又产生了一个疑问,发布另一个问题可能比评论前一个问题更好。
直截了当:我知道这样的东西不会编译
public class Main {
public static void main(String[] args) {
One one = new One();
F f = new F(){ //1
public void foo(){one.bar();} //compilation error
};
one = new One();
}
}
class One { void bar() {} }
interface F { void foo(); }
由于Java如何管理闭包,因为one
它不是 [有效地]最终的 ,依此类推。
但是,这怎么允许呢?
public class Main {
public static void main(String[] args) {
One one = new One();
F f = one::bar; //2
one = new One();
}
}
class One { void bar() {} }
interface F { void foo(); }
不//2
等于//1
?在第二种情况下,我是否不会面临“使用过时的变量”的风险?
我的意思是,在后一种情况下,one = new One();
执行后f
仍然具有过期的副本one
(即引用旧对象)。这不是我们要避免的歧义吗?
尽管方法可以以相同的方式使用,但方法引用不是lambda表达式。我认为这就是造成混乱的原因。下面是Java的工作方式的简化,它不是真正的工作方式,但是足够接近。
假设我们有一个lambda表达式:
Runnable f = () -> one.bar();
这等效于实现的匿名类Runnable
:
Runnable f = new Runnable() {
public void run() {
one.bar();
}
}
这里的规则与匿名类(或方法本地类)的规则相同。这意味着one
需要有效地完成工作。
另一方面,方法句柄:
Runnable f = one::bar;
更像是:
Runnable f = new MethodHandle(one, one.getClass().getMethod("bar"));
与MethodHandle
:
public class MethodHandle implements Runnable {
private final Object object;
private final Method method;
public MethodHandle(Object object, java.lang.reflect.Method method) {
this.object = Object;
this.method = method;
}
@Override
public void run() {
method.invoke(object);
}
}
在这种情况下,分配给的对象将one
作为创建的方法句柄的一部分进行分配,因此one
它本身不一定要有效地最终运行。
问题内容: 我有按钮单击侦听器,并且在方法中我有一个局部变量,例如 为什么Java要求让我最终决定? 问题答案: 当onCreate()方法返回时,您的局部变量将从堆栈中清除,因此它们将不再存在。但是匿名类对象new View.OnClickListener()引用了这些变量。当然,这是错误的行为,因此Java不允许您执行此操作。 最终确定后,它将成为一个常数。因此它存储在堆中,可以在匿名类中安全
问题内容: 关于编译器错误,有一些关于Stack Overflow的主题,解决方案是“将其声明为最终的,您就完成了”,但是对于这个 理论性的 问题,我想检查一下该代码无法编译的逻辑原因是什么: (解决方案:声明为final),而这一点却做到了: 我真的很困惑 不是最终值,它可以多次更改,而的可怜参数只能在其方法体内更改,而是由编译器负责;) 甚至编译器错误也误导了我。: 与什么不同?与内部类不是在
在《生锈的一生》一章中,有一个例子: 为什么他们使用
问题内容: 编辑:我需要更改几个变量的值,因为它们在计时器中运行了几次。我需要在每次迭代中通过计时器不断更新值。我无法将值设置为,因为这将阻止我更新值,但是我遇到了在下面的第一个问题中描述的错误: 我以前写过下面的内容: 我收到错误消息“无法引用用其他方法定义的内部类内部的非最终变量”。 对于名为的价格和名为的,这种情况正在发生。你知道我为什么会遇到这个问题吗?我不明白为什么我需要作最后声明。另外
问题内容: 我在查看有关最终变量的另一个问题,并注意到您可以声明最终变量而无需初始化它们(空白的最终变量)。是否有理由这样做,何时才是有利的? 问题答案: 这对于创建不可变对象很有用: Bla是不可变的(一旦创建,就无法更改,因为颜色是最终的)。但是您仍然可以通过用各种颜色构造它们来创建各种Blas。 例如,另请参阅此问题。 编辑 也许值得一提的是,“空白最终”在Java中具有非常特殊的含义,这似
问题内容: 我读了这个问题不可变对象,并留下了关于不可变对象,并最终场一个问题: 为什么我们需要不可变类中的实例变量为最终变量? 例如,考虑以下不可变的类: 如果在上面的代码中没有set方法,而实例变量仅在构造函数中设置,为什么要求将实例变量声明为final? 问题答案: 有没有 要求 这样做的变量。但是,当您确实明确打算永远不更改变量时,通常这样做是一种好习惯,因为这不仅可以使变量避免错别字或其