2011-01-20 13 views
6

みんな、私はちょうどJavaを学ぼうと試み始めていて、本当に混乱していることに遭遇しました!Java Unicode Confusion

私は使用している本の例をタイプしていました。これは、 charデータ型を示すことです。次のように

コードは次のとおりです。

public class CharDemo 
{ 
public static void main(String [] args) 
{ 
char a = 'A'; 
char b = (char) (a + 1); 
System.out.println(a + b); 
System.out.println("a + b is " + a + b); 
int x = 75; 
char y = (char) x; 
char half = '\u00AB'; 
System.out.println("y is " + y + " and half is " + half); 
} 
} 

私を混乱されたビットは、文、文字の半分=「\ u00AB」です。本書では、\ u00ABはシンボル「1/2」のコードであると述べています。説明したように、私がcmdからプログラムをコンパイルして実行すると、この行で生成されたシンボルは実際には '1/2'になります。

すべてが正常に動作するようです。私はコードで遊んで、いくつかの異なるユニコードを試してみることにしました。私は複数のユニコードテーブルを検索し、それらのどれもが上記の結果と一致するものがないことを発見しました。私はそれがコード/ u00ABは「1/2」のためではなかったし、このために実際にあったことを述べた一人一人に

http://www.fileformat.info/info/unic...r/ab/index.htm だから、Javaはどのような文字セットを使用している、私は、Unicodeがなっていたと思いましたそれだけである、Uni、ただ一つ。私は何時間も検索していますが、/ u00ABが1/2に等しい文字セットを見つけることはできますが、これは私のJavaコンパイラがそれを解釈するものです。

ここにはっきりとわからないものがあります。助けてくれてありがとう!

+3

を私はあなたが直面している問題を理解するために、この記事をお勧めします:[Unicodeとキャラクタセットについて知っておくべき、絶対最小すべてのソフトウェア開発者を絶対にします] (http://www.joelonsoftware.com/articles/Unicode.html) –

答えて

2

Javaに関して素晴らしいことの1つは、ユニコードベースであるということです。つまり、データ文字列だけでなく、関数や変数名にも英語のアルファベット(中国語や数学記号など)でない文字を書くことができます。

ここでは、クラス名と変数名にユニコード文字を使用したコード例を示します。

class 方 { 
    String 北 = "north"; 
    double π = 3.14159; 
} 

class UnicodeTest { 
    public static void main(String[] arg) { 
     方 x1 = new 方(); 
     System.out.println(x1.北); 
     System.out.println(x1.π); 
    } 
} 

Javaは、Unicode標準がはるかに小さい文字セットに値が定義されていた頃に作成されました。当時、これまで必要とされていたすべての文字を16ビットで十分にエンコードできると感じていました。これを念頭において、JavaはUTF-16を使用するように設計されています。実際、charデータ型はもともとは16ビットのUnicodeコードポイントを表現するために使用されていました。

UTF-8文字セットは、RFC 2279で指定されています。

UTF-16文字セットは、UTF-16文字セットは、16ビット量を使用し、従って、バイト順序に敏感であるRFC 2781

によって指定されています。これらの符号化では、ストリームのバイト順序は、Unicode文字 '\ uFEFF'によって表される最初のバイト順序マークによって示される。次のようにバイトオーダーマークが処理されます。

When decoding, the UTF-16BE and UTF-16LE charsets ignore byte-order marks; when encoding, they do not write byte-order marks. 

When decoding, the UTF-16 charset interprets a byte-order mark to indicate the byte order of the stream but defaults to big-endian if there is no byte-order mark; when encoding, it uses big-endian byte order and writes a big-endian byte-order mark. 

Also see this

+2

UTF-8とUTF-16 **は**文字セットではありません。 **同じUnicodeの2つの異なる可変幅のエンコーディングです。 – tchrist

4

\u00ab文字が1/2文字ではありません。 Unicode.org Webサイトのdefinitive code pageを参照してください。

あなたが見ているのは、デフォルトの文字エンコーディングがUTF-8またはLatin-1でないプラットフォームでSystem.outPrintStreamを使用した結果です(私は思います)。おそらく@ axtavtの答えで示唆されているように、いくつかのWindowsの文字セットですか? (また\u00ab1/2 ...ではなく、いくつかの「スプラット」の文字として表示されている理由のもっともらしい説明があります。)

を(Unicodeとラテン1では、\00BD1/2文字のコードポイントです。)

16

これは、Windowsプラットフォーム上でコンソールエンコーディングの不一致と、よく知られた問題です。

Java Runtimeは、システムコンソールで使用されているエンコーディングがシステムのデフォルトエンコーディングと同じであると想定しています。ただし、Windowsでは2つの別々のエンコード、ANSI code page (system default encoding) and OEM code page (console encoding)を使用します。

コンソールにUnicode文字U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARKを書くしようとするので、Javaランタイムは、コンソールのエンコーディングは、このUnicode文字が0xABとして表されるANSIエンコーディング(それはあなたのケースでWindows-1252である)、であることを期待しています。ただし、実際のコンソールエンコーディングは、0xABがを意味するOEMエンコーディング(ご使用の場合はCP437)です。

したがって、System.out.println()でWindowsコンソールにデータを印刷すると、間違った結果になります。

正しい結果を得るには、代わりにSystem.console().writer().println()を使用してください。

+0

ありがとう、これは理にかなっていますが、Windowsコンソールにデータを印刷すると間違った結果が出ることになります。この例はJavaの本から直接得られたもので、作者はABが半分になることを知っていました。彼はこれを説明していないという点でこれはちょうど貧弱な文章ですか? – Nick

+1

@ニック:それは貧弱な文章です。おそらく著者がASCII以外の文字で作業することはめったにないので、この問題はよく知られていませんでした。 – axtavt

+1

+1。それは本当にばかげている。 JavaとWindowsはどちらも、メモリ内でUTF-16LEとしてエンコードされたネイティブのUnicode文字列を使用します。しかし、文字通りのエンコード・デコード・サイクルを経ずにバイトを通らずにお互いに話すことはできません。 – bobince

3

0xABは、Windows端末が既定で使用するものであるCodepage 437で、no matter what codepage you actually setです。

実際、char値はJavaプログラムの "«"文字を表し、その文字をGUIでレンダリングするか、または純粋なオペレーティングシステムで実行すると、その文字を取得します。 Windowsでも適切な出力を見たい場合は、CMDのフォント設定を「ラスタフォント」(左上のアイコン、プロパティ、フォントタブをクリック)から切り離してください。例えば、ルシーダコンソールで、私はこれを行うことができます:

C:\Users\Documents>java CharDemo 
131 
a + b is AB 
y is K and half is ½  

C:\Users\Documents>chcp 1252 
Active code page: 1252 

C:\Users\Documents>java CharDemo 
131 
a + b is AB 
y is K and half is « 

C:\Users\Documents>chcp 437 
Active code page: 437 
+2

ああ、あなたが彼/彼女に会うことがあれば、頭であなたの本の著者を打つ。 – themel

+0

別の本のおすすめはありますか?それは、非常に基本的なものから基本的なものまで、絶対に始めから始める必要があります。 – Nick