ThreadLocal的空指针异常问题
生活随笔
收集整理的這篇文章主要介紹了
ThreadLocal的空指针异常问题
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在進(jìn)行g(shù)et()之前,必須先進(jìn)行set(),否則可能會(huì)報(bào)空指針異常
public class ThreadLocalNPE {ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();public void set(){threadLocal.set(Thread.currentThread().getId());}/*** 這里的返回值使用long的時(shí)候,如果沒有set()就調(diào)用get()那么會(huì)報(bào)空指針異常,因?yàn)闋可娴讲鹣滢D(zhuǎn)換(將對(duì)象類型轉(zhuǎn)換為基本類型)* @return*/public Long get(){return threadLocal.get();}public static void main(String[] args) {ThreadLocalNPE threadLocalNPE = new ThreadLocalNPE();System.out.println(threadLocalNPE.get());new Thread(() -> {threadLocalNPE.set();long threadId = threadLocalNPE.get();System.out.println(threadId);}).start();} }ThreadLocal拆裝箱引起的空指針異常
public class SpringbootApplication {/*** 登錄方法** @param userId*/public void login(Integer userId) {UserInfoHolder.userInfoHolder.set(userId);System.out.println("用戶登錄了," + "保存用戶id:" + userId);order();}/*** 下訂單方法*/public void order() {System.out.println("訂單服務(wù)獲取了用戶id:" + UserInfoHolder.userInfoHolder.get() + ",下了訂單");logistics();}/*** 物流方法*/public void logistics() {UserInfoHolder.userInfoHolder.remove();System.out.println("物流服務(wù)獲取了用戶id:" + UserInfoHolder.get() + ",發(fā)出了物流");}/*** ThreadLocal*/static class UserInfoHolder {private static ThreadLocal<Integer> userInfoHolder = new ThreadLocal<>();/*** 自定義了一個(gè)get方法,返回int類型** @return*/public static int get() {return userInfoHolder.get();}}public static void main(String[] args) throws Exception {new SpringbootApplication().login(666);} }報(bào)了空指針異常
看下原因:
以下是userInfoHolder.get()的get方法的源碼:
public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);return value;}protected T initialValue() {return null;}可以發(fā)現(xiàn)它返回的是一個(gè)泛型T,而這個(gè)T的類型是在ThreadLocal初始化就定義好的了,同時(shí)如果沒有做任何初始化賦值,或者設(shè)值操作,默認(rèn)就會(huì)返回null
以下ThreadLocal類的定義:
public class ThreadLocal<T> { }而上述測(cè)試代碼中,初始化ThreadLocal時(shí),定義的類型是Integer,所以get方法返回的也是Integer類型,由于調(diào)用了ThreadLocal的remove操作,所以默認(rèn)會(huì)返回null,照理說返回null也沒什么問題,關(guān)鍵就是方法里返回參數(shù)用的是int類型做接收,這樣就會(huì)自動(dòng)拆裝箱,而由于值為null,自然就引起了空指針異常。返回值改為Integ返回er就ok了
?
總結(jié)
以上是生活随笔為你收集整理的ThreadLocal的空指针异常问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 收不回来的value
- 下一篇: ThreadLocal在Spring中的