1. 程式人生 > >用java String類的getBytes(String charsetName)和String(byte[] bytes, String charsetName)解決亂碼問題

用java String類的getBytes(String charsetName)和String(byte[] bytes, String charsetName)解決亂碼問題

Java中String的資料是如何儲存的,檢視原始碼就可以知道,String的資料是儲存在char[] value這樣一個成員變數中的,char型別的大小在java中是2個位元組 
我們還知道,現在普遍使用的unicode版本是UCS-2,就是使用2個位元組表示一個字元的unicode版本,這就對上了,java使用的就是UCS-2標準,所以,String中的value中儲存的都是一個個數字

比如’你’的unicode編碼是4f60,看下面的測試程式碼

char c = '你';
System.out.println(Integer.toHexString(c));
System.out.println(Integer.valueOf(c));
System.out.println(c);

結果是: 
4f60 
20320 

所以呢,現在我們知道了String內部其實儲存的是未經任何編碼的unicode編碼,就是那個對應字元的編碼,然後再看我們這兩個方法:

getBytes(charsetname) 
意思是根據這個編碼來獲取位元組陣列 
這又是什麼意思呢? 
就是說將記憶體中的unicode編碼轉換為charsetname格式所對應的位元組陣列 
比如’你’,轉換為utf-8是三個字接,所以得到的位元組陣列就是三個位元組的 
即[e4 bd a0]

然後String(bytes,charsetname)呢

意思就是將bytes這個位元組陣列按照charsetname解釋,組裝為一個String儲存起來 
例如上面那個位元組陣列[e4 bd a0],按照utf-8解釋的話,儲存起來就是”你”這個字串,如果按照其他編碼解釋,則不會解釋為”你”

說個其他的,為什麼在servlet中處理引數一般都需要這麼一句了來控制編碼:

String str = new String(param.getBytes(“ISO-8859-1”),”UTF-8”);

其實這很好理解,瀏覽器傳過來的位元組資料是UTF-8編碼的,然後web容器預設這個位元組資料是ISO-8859-1編碼的,所以使用ISO-8859-1把這個位元組資料轉換變成了String儲存起來,相當於是進行了下面這個操作:

String s = new String(UTF8Bytes,”ISO-8859-1”);

注意這個編碼是單位元組的,也就是將每一個位元組都轉換成了unicode編碼,幸好是這樣,使我們有機會將這個String再轉換成和原來一模一樣的位元組陣列,所以才有了我們平時用的最多的那一句編碼處理的程式碼

最後,想再說一下,對編碼這塊不瞭解的原因,是我們理解錯誤,我們必須知道的是:

java內部儲存字串使用的unicode編碼 
我們通常會聽到有人說:“我需要將String由ISO-8859-1轉換為GBK編碼”,這又是怎麼回事呢?實際上,我們並不是要“將 一個由ISO-8859-1編碼的String轉換為GBK編碼的String”,反覆說明的是,JAVA中的String都是unicode編碼的,所以不存在“ISO- 8859-1編碼的String”或“GBK編碼的String”這樣的說法。而需要轉換的唯一的原因是String進行了錯誤的編碼。我們經常會碰到由ISO-8859- 1轉換為諸如GBK/UTF-8等等這樣的需求。所謂的轉換過程是:String –> byte[] –>String

相關推薦

java StringgetBytes(String charsetName)String(byte[] bytes, String charsetName)解決亂碼問題

Java中String的資料是如何儲存的,檢視原始碼就可以知道,String的資料是儲存在char[] value這樣一個成員變數中的,char型別的大小在java中是2個位元組 我們還知道,現在普遍使用的unicode版本是UCS-2,就是使用2個位元組表示一個字元的unicode版本,這就對上了,java

javaString中的nullisEmpty()的區別

程式碼示例如下: package com.example; public class MyClass { public static void main(String[] args){

JAVA String型去除空格字符

ref eal 字符 hid clas rep 其中 空白 一個 1. String.trim()trim()是去掉首尾空格 2.str.replace(" ", ""); 去掉所有,包括首尾、中間 str.replace("需要替換的符號",“替換後的符號

String 型equals方法int == 方法效率比較

方法 新建 錯誤 == 總數 進行 差距 拆裝箱 自己 最近寫了一個遞歸方法,在進行比較判斷的時候,因為都是integer類型,而integer類型在大於127或者小於-128時會在新建一個,這是因為integer類型的拆裝箱機制, 之前沒有考慮過equals方法和 =

string的常用屬性方法

靜態方法 string.Format——格式化字串 string.Concat(string,string)——字串連線 string.Compare(string,string)——字串比較。相等返回0,大於返回1,小於返回-1 string.CompareNoCase——字串比較不區分大小寫 例項方法

關於string的倒序反向迭代器

原文連結http://blog.csdn.net/easyiocp/article/details/7172434 如何用c++來實現字串的倒序呢 我直接想到的是利用反向迭代器reverse_iterator:rbegin()和rend(): string str1("12

JAVA給數據庫增加修改數據代碼

pre dst set mod string statement exec modify str public class DeptDao{ public int a dd(Connection conn,Dept dept) throws Except

java數組模擬登錄註冊功能

ann print copy int oid java user AS port package com.linkage.login; import java.util.Scanner; public class user { // 存儲用戶名和密碼 publi

SM框架新特性關於Java配置完全代替XML

專案目錄結構   從Spring3.0,@Configuration用於定義配置類,可替換xml配置檔案,被註解的類內部包含有一個或多個被@Bean註解的方法, 這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApp

Java實現傳送http的getpost請求

import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; imp

Java反射之——Java獲取中成員變數建構函式的資訊

我們無論是獲取成員變數資訊,亦或者是獲取建構函式的資訊,都必須獲取類的類型別,然後通過類的類型別進行對成員變數和建構函式的操作。 注:成員變數和建構函式也都是物件,前者是Feild的物件,在java.lang.reflec.Feild中封裝了對成員變數的資訊。後者是Constructor的物件,

【譯】12. Java反射——的動態載入重新載入

博主最近比較忙,爭取每週翻譯四篇。等不急的請移步原文網頁。  =====================================================================================

JAVA——包裝的自動裝箱拆箱

關於JAVA的包裝類自動拆箱和裝箱,有很多人做過介紹,但筆者發現說的不夠簡潔,而這個問題在面試、筆試中又經常涉及,故筆者將蒐集到的資訊與大家分享下: 包裝類(原始型別對應的類,即Boolean, By

深入java)建構函式物件建立的記憶體分配

之前的文章總結了java一些較為常用的關鍵字,現在我們要進入到類裡面,總結類的特徵(其中包括了記憶體和建構函式,gc垃圾回收),java中類的繼承和初始化順序(會涉及到ClassLoader),java多型的深入,java抽象類、介面的深入理解和例子。今天從類開

java抽象+繼承+super用法this異同

抽象類 抽象類顧名思義也是類,其命名也暗示它是在類的基礎上加以限制(加強條件)而來 1 定義限制 至少含有一個抽象方法,其餘屬性,方法皆與普通類一致 抽象方法是用abstract宣告的方法,無方法體,專門用來給子類繼承

java的初始化物件的例項化區別

在程式RUN的一瞬間,什麼類啊,靜態的東西啊(靜態塊,靜態方法,靜態屬性),刷刷刷的就在記憶體中載入(你可以看作初始化)了,只加載一次,然後main方法開始執行(這就是為什麼main方法必須是靜態的原

Java求整數區間[a,b][c,d]的交集、並集

1. 求整數區間[a,b]和[c,d]的交集、並集 package cn.oop.nk; /** * 求整數區間[a,b]和[c,d]的交集、並集 * @author 溫暖wk * */ public class Demo02 { pu

java集合HashMap獲取鍵

1.獲取HashMap鍵 package com.mypractice.third; import java.util.HashMap; import java.util.Map; import

java訪問的私有變數方法

import java.lang.reflect.Field;   import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; class A {       pr

Java普通中使用requestsession

很多人都想,在一個普通類裡如何才能獲取系統的request或session,我也找了,但沒有,就自己實現了一下,期待需要的有緣人,希望能幫到一點點。   具體如下:   實現步驟:   1.定義一個執行緒類,普通的:   類裡最主要的就是定義了一個引數:   private static ThreadLoc