java怎么解決亂碼?關(guān)于這個問題我已經(jīng)回答過很多次私植,但許多朋友可能還沒有理解忌栅,本篇文章再來詳細為大家解答一下亂碼是如何產(chǎn)生的?java怎么解決亂碼?等相關(guān)問題,希望對大家有所幫助曲稼。
java怎么解決亂碼?
java在字符串中統(tǒng)一用Unicode表示索绪。
對于任意一個字符串:String string = “測試字符串”;
如果源文件是GBK編碼,操作系統(tǒng)默認環(huán)境編碼也為GBK贫悄,那么編譯的時候瑞驱,JVM將按照GBK編碼將字節(jié)數(shù)組解析為字符,然后將字符轉(zhuǎn)換為Unicode格式的字節(jié)數(shù)組窄坦,作為內(nèi)部存儲(字節(jié)數(shù)組→字符→Unicode字節(jié)數(shù)組)
當打印這個字符串時唤反,JVM根據(jù)操作系統(tǒng)本地的語言環(huán)境,將Unicode轉(zhuǎn)換為GBK鸭津,然后操作系統(tǒng)將GBK格式的內(nèi)容顯示出來彤侍。
當源碼文件是UTF-8, 我們需要通知編譯器源碼的格式,javac -encoding utf-8 … , 編譯時逆趋,JVM按照utf-8 解析成字符盏阶,然后轉(zhuǎn)換為unicode格式的字節(jié)數(shù)組, 那么不論源碼文件是什么格式闻书,同樣的字符串名斟,最后得到的unicode字節(jié)數(shù)組是完全一致的,顯示的時候魄眉,也是轉(zhuǎn)成GBK來顯示(跟OS環(huán)境有關(guān))
亂碼是如何產(chǎn)生的?
本質(zhì)上都是由于字符串原本的編碼格式與讀取時解析用的編碼格式不一致導(dǎo)致的砰盐。
亂碼指的是程序顯示出來的字符文本無法用任何語言去解讀。一般情況下會包含大量的?杆融。亂碼問題是所有計算機用戶或多或少會遇到的問題楞卡。造成亂碼的原因就是因為使用了錯誤的字符編碼去解碼字節(jié)流,因此當我們在思考任何跟文本顯示有關(guān)的問題時,請時刻保持清醒:當前使用的字符編碼是什么蒋腮。只有這樣淘捡,我們才能正確分析和處理亂碼問題。
例如最常見的網(wǎng)頁亂碼問題池摧。如果你是網(wǎng)站技術(shù)人員焦除,遇到這樣的問題,需要檢查以下原因:
● 服務(wù)器返回的響應(yīng)頭Content-Type沒有指明字符編碼
● 網(wǎng)頁內(nèi)是否使用META HTTP-EQUIV標簽指定了字符編碼
● 網(wǎng)頁文件本身存儲時使用的字符編碼和網(wǎng)頁聲明的字符編碼是否一致
java代碼中的亂碼問題如何解決呢?
例如:String s = “測試字符串”;
其中g(shù)etBytes()是將Unicode轉(zhuǎn)換為操作系統(tǒng)默認格式的字節(jié)數(shù)組作彤,即“測試字符串”的GBK格式膘魄,new String (bytes, Charset) 中的charset 是指定讀取byte的方式,這里指定為UTF-8竭讳,即把bytes的內(nèi)容當做UTF-8來讀取创葡。
如下兩種方式得到的結(jié)果都是正確的,因為它們的源內(nèi)容編碼和解析用的編碼是一致的绢慢。
那么灿渴,如何利用getBytes 和 new String() 來進行編碼轉(zhuǎn)換呢?
網(wǎng)上流傳著一種錯誤的方法:
這種方式是完全錯誤的,因為getBytes 的編碼與 UTF-8 不一致胰舆,肯定是亂碼骚露。
但是為什么在tomcat 下,使用 new String(s.getBytes(“iso-8859-1”) ,”GBK”) 卻可以用呢?
答案是:
tomcat 默認使用iso-8859-1編碼缚窿, 也就是說棘幸,如果原本字符串是GBK的,tomcat傳輸過程中倦零,將GBK轉(zhuǎn)成iso-8859-1了误续,默認情況下,使用iso-8859-1讀取中文肯定是有問題的光绕,那么我們需要將iso-8859-1 再轉(zhuǎn)成GBK女嘲, 而iso-8859-1 是單字節(jié)編碼的畜份,即他認為一個字節(jié)是一個字符诞帐, 那么這種轉(zhuǎn)換不會對原來的字節(jié)數(shù)組做任何改變,因為字節(jié)數(shù)組本來就是由單個字節(jié)組成的爆雹,如果之前用GBK編碼停蕉,那么轉(zhuǎn)成iso-8859-1后編碼內(nèi)容完全沒變, 則 s.getBytes(“iso-8859-1”) 實際上還是原來GBK的編碼內(nèi)容則 new String(s.getBytes(“iso-8859-1”) ,”GBK”) 就可以正確解碼了钙态。 所以說這是一種巧合慧起。
如何正確的將GBK轉(zhuǎn)UTF-8 ? (實際上是unicode轉(zhuǎn)UTF-8)
UTF-8 轉(zhuǎn)GBK原理也是一樣
其實核心工作都由getBytes(charset)做了。getBytes的JDK描述:Encoding this String into a sequence of bytes using the named charset,storing the result into a new byte array.
可以幫助我們輕松的按照指定編碼讀寫文件册倒。
以上就是java怎么解決亂碼的詳細內(nèi)容蚓挤。
分享給大家看看,不論是用于鞏固基礎(chǔ),還是在面試中提高競爭力都可以收藏一份灿意,有空多看看估灿,下面展示部分截圖。
(一). 基礎(chǔ)
1馅袁、Java 基本功
Java 入門(基礎(chǔ)概念與常識)
Java 語法
基本數(shù)據(jù)類型
方法(函數(shù))
2、Java 面向?qū)ο?/p>
類和對象
面向?qū)ο笕筇卣?/p>
修飾符
接口和抽象類
其它重要知識點
3、Java 核心技術(shù)
集合
異常
多線程
文件與 I\O 流
(二). 并發(fā)
1、并發(fā)容器
JDK 提供的并發(fā)容器總結(jié)
ConcurrentHashMap
CopyOnWriteArrayList
ConcurrentLinkedQueue
BlockingQueue
ConcurrentSkipListMap
2祝辣、線程池
使用線程池的好處
Executor 框架
(重要)ThreadPoolExecutor 類簡單介紹
(重要)ThreadPoolExecutor 使用示例
幾種常見的線程池詳解
ScheduledThreadPoolExecutor 詳解
線程池大小確定
3、樂觀鎖與悲觀鎖
何謂悲觀鎖與樂觀鎖
樂觀鎖常見的兩種實現(xiàn)方式
樂觀鎖的缺點
CAS與synchronized的使用情景
(三). JVM
1裳朋、Java內(nèi)存區(qū)域
概述
運行時數(shù)據(jù)區(qū)域
HotSpot 虛擬機對象探秘
重點補充內(nèi)容
2、JVM垃圾回收
揭開 JVM 內(nèi)存分配與回收的神秘面紗
對象已經(jīng)死亡?
垃圾收集算法
垃圾收集器
3、JDK 監(jiān)控和故障處理工具
JDK 命令行工具
JDK 可視化分析工具
(四)網(wǎng)絡(luò)钦奋、linux、數(shù)據(jù)結(jié)構(gòu)與算法疙赠、數(shù)據(jù)庫付材、系統(tǒng)設(shè)計、必會工具圃阳、面試指南
因為篇幅有限厌衔,其他內(nèi)容就不一一展示了,這本進階筆記總共有512頁捍岳。對于想要進階的小伙伴來說應(yīng)該會很有幫助富寿,希望也能幫助到你。