一主題關於JAVA的中文問題 JAVA的中文問題比較突出
主要表現在控制面板輸出
JSP頁面輸出和數據庫訪問上
本文盡量避開字體問題
而只談編碼
通過本文
你可以了解JAVA中文問題的由來
問題的解決方法
其中提了一下用JDBC訪問數據庫的方法
二問題描述 )在中文W
中文窗口編譯和運行
用的是國際版的JDK
連接的是中文W
下的Cp
編碼的SQL SERVER數據庫
J:\exercise\demo\encode\HelloWorld>make
Created by XCompiler
PhiloSoft All Rights Reserved
Wed May
:
:
CST
J:\exercise\demo\encode\HelloWorld>run
Created by XRunner
PhiloSoft All Rights Reserved
Wed May
:
:
CST
中文
[B@
bc
b
[B@
b
b
[B@
b
中文
中文
????
中文
中文
????
??
??
??
)如果在中文W
的西文窗口(編碼為
)下編譯
用JAVA運行則由於無字體而無法正常顯示
如果象上面一樣在中文W
的中文窗口運行
輸出為
J:\exercise\demo\encode\HelloWorld>run
Created by XRunner
PhiloSoft All Rights Reserved
Wed May
:
:
CST
????
[B@
bc
b
a
[B@
b
b
a
[B@
b
a
????
????
????
????
????
????
中文
中文
????
三)分析
)出現有亂碼(也就是?)
由於只出現?而沒出現小方框
說明只是編碼有問題
而不是字體問題
在編碼中
如果從一種字符集轉換到別一種字符集
比較典型的是從GB
轉換到ISO
_
(即ASCII)
那麼很多漢字(半個漢字)是無法映射到西文字符中去的
在這種情形下
系統就把這些字符用?代替
同樣
也存在小字符集無法到大字符集的情況
具體原因這裡就不詳談了
)出現了中文環境編譯
中文環境運行時漢字顯示有正確也有不正確的地方
同樣
在西文環境下編譯
在中文環境下運行時也出現類似情況
這是由於自動(默認)或手工(也就new String(bytes[
encode])和bytes getBytes([encode]))轉碼的結果
)在JAVA源文件
>JAVAC
>Class
>Java
>getBytes()
>new String()
>顯示的過程中
每一步都有編碼的轉換過程
這個過程總是存在的
只是有的時候用默認的參數進行
下面我們一步一步分析為什麼出現上面的情形
)這裡是源代碼
HelloWorld
java:
public class HelloWorld
{
public static void main(String[] argv){
try{
System
out
println(
中文
);//
System
out
println(
中文
getBytes());//
System
out
println(
中文
getBytes(
GB
));//
System
out
println(
中文
getBytes(
ISO
_
));//
System
out
println(new String(
中文
getBytes()));//
System
out
println(new String(
中文
getBytes()
GB
));//
System
out
println(new String(
中文
getBytes()
ISO
_
));//
System
out
println(new String(
中文
getBytes(
GB
)));//
System
out
println(new String(
中文
getBytes(
GB
)
GB
));//
System
out
println(new
String(
中文
getBytes(
GB
)
ISO
_
));//
System
out
println(new String(
中文
getBytes(
ISO
_
)));//
System
out
println(new
String(
中文
getBytes(
ISO
_
)
GB
));//
System
out
println(new
String(
中文
getBytes(
ISO
_
)
ISO
_
));//
}
catch(Exception e){
e
printStackTrace();
}
}
}
為了方便起見
在每個轉換的後面加了操作序號
分別為
)需要說明的是
JAVAC是以系統默認編碼讀入源文件
然後按UNICODE進行編碼的
在JAVA運行的時候
JAVA也是采用UNICODE編碼的
並且默認輸入和輸出的都是操作系統的默認編碼
也就是說在new String(bytes[
encode])中
系統認為輸入的是編碼為encode的字節流
換句話說
如果按encode來翻譯bytes才能得到正確的結果
這個結果最後要在JAVA中保存
它還是要從這個encode轉換成Unicode
也就是說有bytes
>encode字符
>Unicode字符的轉換
而在String
getBytes([encode])中
系統要做一個Unicode字符
>encode字符
>bytes的轉換
在這個例子中
除那個英文窗口編碼的時候除外
其實情形下默認編碼都是GBK(在本例中
我們暫且把GBK和GB
等同看待)
)由於在未指明在上面的兩個用代碼實現的轉換中
如果未指定encode
系統將采用默認的編碼(這裡為GBK)
我們認為上面的
和
是一樣的
和
和
也是一樣的
所以我們在討論中將只討論
其中的
只是用於測試
不在我們的討論范圍之內
)下面我們來跟蹤程序中的
中
字的轉換歷程
我們先說在中文窗口下作的編譯和運行過程
注意在下面的字母下標中
我有意識地使用了一些數字
以表示相同
相異還是相關
)我們先以上面的
個代碼段中的的代碼
為例
步驟 內容 地點 說明
C
HelloWorld
java C
泛指一個GBK字符
U
JAVAC讀取 U
泛指一個Unicode字符
C
getBytes()第一步 JAVA先和操作系統交流
B
B
getBytes()第二步 然後返回字節數組
C
new String()第一步 JAVA先和操作系統交流
U
new String()第二步 然後返回字符
C
println(String) 能顯示
中
字
內容和原來的相同
)然後再以代碼段
為例
我們注意到只是
步驟 內容 地點 說明
C
HelloWorld
java C
泛指一個GBK字符
U
JAVAC讀取 U
泛指一個Unicode字符
C
getBytes()第一步 JAVA先和操作系統交流
B
B
getBytes()第二步 然後返回字節數組
C
C
new String()第一步 JAVA先和操作系統交流
這時解析錯誤
U
U
new String()第二步 然後返回字符
C
C
println(String) 由於中字給分成了兩半
在ISO
_
中剛好也沒有字符
能映射上
所以顯示為
??
在上面的示例中
中文
兩個字就顯示為
????
)在完全中文模式下的其它情形類似
我就不多說了
)我們接著看為什麼在西文DOS窗口下編譯出來的類在中文窗口下也出現類似情形
特別是為什麼居然有的情形下還能正確顯示漢字
)我們還是先以代碼段
為例
步驟 內容 地點 說明
C
C
HelloWorld
java C
C
分別泛指一個ISO
_
字符
中
字被拆開
U
U
JAVAC讀取 U
U
泛指一個Unicode字符
C
C
getBytes()第一步 JAVA先和操作系統交流
這時解析錯誤
B
B
B
B
getBytes()第二步 然後返回字節數組
C
C
new String()第一步 JAVA先和操作系統交流
U
U
new String()第二步 然後返回字符
C
C
println(String) 雖然同是兩個字符
但已不是最初的
兩個ISO
_
字
符
而是
兩個BGK字符
中
顯示成了
??
而
中文
就顯示成了
????
)下面我們以代碼段
為例
因為它能正確顯示漢字
步驟 內容 地點 說明
C
C
HelloWorld
java C
C
分別泛指一個ISO
_
字符
中
字被拆開
U
U
JAVAC讀取 U
U
泛指一個Unicode字符
C
C
getBytes()第一步 JAVA先和操作系統交流(注意還是正確的哦!)
B
B
getBytes()第二步 然後返回字節數組(這是很關鍵的一步!)
C
new String()第一步 JAVA先和操作系統交流(這是更關鍵的一步
JAVA已經知道B
B
要解析成一個漢字!)
U
new String()第二步 然後返回字符(真是一個項兩!U
包含了U
U
的信息)
C
println(String) 這就原來的
中
字
很委屈被JAVAC冤枉了一回
不過被程序員撥亂反正了一下!當然
中文
兩個字都能正確顯示了!
)那為什麼有的時候用JDBC的
new String(Recordset
getBytes(int)[
encode])
Recordset
getSting(int)
Recordset
setBytes(String
getBytes([encode]))
和
Recordset
setString(String)
的時候會出現亂碼了呢?
其實問題就出現在編寫JDBC的的也考慮了編碼問題
它從數據庫讀取數據後
可能自作主張做了一個從GB
(默認編碼)到Unicode的轉換
我的這個WebLogic For SQL Server的JDBC Driver就是這樣的
當我讀字串的時候
發出讀到的不是正確的漢字
可恨的是我卻可以直接寫漢字字串
這讓人多少有點難以接受!
也就是說
我們不得不在讀或寫的時候進行轉碼
盡管這個轉碼有的時候不是那麼明顯
這是因為我們使用了默認的編碼進行轉碼
JDBC Driver
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25432.html