熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Javascript >> 正文

關於JAVA的中文問題

2013-11-23 17:57:41  來源: Javascript 

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