JDK1.8之後匿名内部類通路方法中的局部變量不用加final修飾
今天在學習ThreadLocal類,在一個方法中寫了一個匿名内部類,然後使用方法中的局部變量,發現不用加final修飾變量
但是如果修改了變量值,在ide中會報紅顯示,局部變量必須是有效的final類型
附上代碼,可以學習一下ThreadLocal
package com.edou.test;
import org.junit.Test;
/**
* @ClassName TestInnerClass
* @Description 測試匿名内部類通路局部變量是否加final
* @Author 中森明菜
* @Date 2020/9/27 8:46
* @Version 1.0
*/
public class TestInnerClass {
@Test
public void testRef() {
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("test1");
Runnable r1 = () -> {
threadLocal.set("test2");
String result = threadLocal.get();
// test2
System.out.println(result);
};
r1.run();
Runnable r2 = () -> {
threadLocal.set("test3");
String result = threadLocal.get();
// test3
System.out.println(result);
};
r2.run();
}
@Test
public void testBasicValue() {
int a = 1;
Runnable r = () -> {
// a = 2
System.out.println(a);
};
r.run();
}
}
在testRef中,局部變量是引用類型,我們改變的是它内部的變量值,并沒有改變它自身的引用位址,但是如果我們在lamda中給局部變量設定 新的引用位址,也就是改變它的指針指向,也會報錯。
在testBasicValue中,我們的局部變量是基本數值類型,如果在lamda中通路不加final沒問題,但是如果修改變量值,也會爆紅。
上面是用lamda表達式實作的,下面是用匿名内部類實作的案例。
package cn.edou.thread;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1(){
ThreadLocal<String> tl = new ThreadLocal<String>();
tl.set("hello");
System.out.println(Thread.currentThread().getName());
new Thread(){
public void run() {
tl.set("world");
System.out.println(Thread.currentThread().getName());
System.out.println(tl.get());
}
}.start();
System.out.println(tl.get());
}
@Test
public void fun2(){
Map<Thread,String> map = new HashMap<Thread, String>();
map.put(Thread.currentThread(), "hello");
new Thread(){
public void run() {
System.out.println(map.get(Thread.currentThread()));
}
}.start();
System.out.println(map.get(Thread.currentThread()));
}
}
/*
* ThreadLocal内部結構是Map
*/
class TL<T> {
private Map<Thread,T> map = new HashMap<Thread,T>();
public void set(T data){
map.put(Thread.currentThread(), data);
}
public T get(){
return map.get(Thread.currentThread());
}
public void remove(){
map.remove(Thread.currentThread());
}
}