Java细节,,Lambda表达式中使用this会怎么样?
最近根据需求,改了下安卓App的登录界面,里面计算短信发送时间的部分发现一个很有意思的地方。
一开始用的timer写的:
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@SuppressLint("SetTextI18n")
public void run() {
runOnUiThread(() -> {
if (timerCount > 0){
hintView.setText(timerCount + "秒");
}else {
hintView.setEnabled(true);
hintView.setText("重新发送");
timerCount = TIME_COUNT;
timer.cancel();
}
timerCount--;
});
}
}, 0 , 1000);
后面想玩点骚操作,利用一下View的post函数计时:
hintView.postDelayed(new Runnable() {
@Override
public void run() {
if (timerCount > 0){
hintView.setText(timerCount + "秒");
hintView.postDelayed(this, 1000);
}else {
hintView.setEnabled(true);
hintView.setText("重新发送");
timerCount = TIME_COUNT;
}
timerCount--;
}
}, 1000);
那问题来了,我把这个Runnable写成Lambda表达式里面的this会怎么样呢?
先理解下 Lambda表达式。
Lambda表达式是对象吗?
也许根本不用问,大家都知道不是,根据《Java核心技术 卷一》所写:
lambda 表达式是一个可传递的代码块,可以在以后执行一次或多次。
Lambda表达式中使用this会怎么样?
sorry you,这里的this会报红,出错了,这里的this是外部类对象。
hintView.postDelayed(() -> {
if (timerCount > 0){
hintView.setText(timerCount + "秒");
hintView.postDelayed(this, 1000);
}else {
hintView.setEnabled(true);
hintView.setText("重新发送");
timerCount = TIME_COUNT;
}
timerCount--;
}, 1000);
像这样
很神奇啊,明明在使用Runnable的时候完全没问题,改成Lambda表达式就不行了。
神奇的编译器
实际呢,还有一点很神奇,这里居然不能使用 Alt + enter
但是去掉带this的那一行,就可以了
结论
Lambda表达式中使用this实际使用的是当前类,而使用匿名类是可以获得this对象的。