2012-03-22 20 views
7

こんにちはみんなは:Java:文字列のバイトサイズ。

文字サイズ:2

文字サイズ:1

私は考え、私は次のコード

System.out.println("Character size:"+Character.SIZE/8); 
System.out.println("String size:"+"a".getBytes().length); 

出力し、これを見つけて驚きました1つの文字列が1つの文字と同じ(またはそれ以上の)バイトを占める必要があるとします。特に、イム不思議で

---

私は、その大きさはフィールド(文字、文字列、論理値、ベクトル、などの性質に応じて増加しますどのようにそれでいくつかのフィールドを持つJava Beanを持っている場合..)私はすべてのJavaオブジェクトが(おそらく最小限の)フットプリントを持っていると仮定しています。そして、これらのフットプリントの中で最小のものが単一の文字であると仮定しています。ですから、その基本的な前提をテストするために、私は上記のコードから始めました。そして、印刷ステートメントの結果は直観に反するようです。

Javaが文字列と文字列をデフォルトで保存/シリアル化する方法についての洞察は、非常に有益です...ありがとうございます。

+5

文字列の長さは、それに含まれる文字数です。文字は2バイト以上で符号化することができます。 – Oded

+4

文字列はおそらくUTF-8でエンコードされているため、 "a"は1バイトしかかかりません。 –

+4

[すべてのソフトウェア開発者の絶対的な最小値、絶対にUnicodeと文字セットについて知っておく必要があります(言い訳はありません)](http://www.joelonsoftware.com/articles/Unicode.html) – Oded

答えて

10

getBytes()は、デフォルトのエンコーディング(おそらくISO-8859-1)でStringを出力しますが、内部文字charは常に2バイトです。内部的には、Javaは常に2バイトのcharを持つchar配列を使用します。エンコードについて詳しく知りたい場合は、質問コメントのOdedによるリンクを読んでください。

+3

参考までに、 'getBytes()'は実際にあなたに 'String'の実際のメモリ消費量を伝えていません。 –

+0

私はあなたのこの声明が正しいとは思わない:「内部的にJavaは常に2バイトのcharを持つchar配列を使います。このリンクを見ることができます:http://javarevisited.blogspot.com.tr/2012/01/get-set-default-character-encoding.html私にとっては、Javaはコード内でデフォルトのエンコーディングとしてUTF-8を使用していました。 –

+0

@KorayTugay JavaでUnicodeの内部メモリ表現がどのようなものか混在している可能性があります(文字列のようなCharSequenceの実装はすべて、UTF-16形式で2バイトの文字を使用しています)、Javaの内部表現(ファイル、ネットワーク)を特定のバイトエンコーディングに変換します。あなたのJavaバージョン(これは...?)が内部的にUTF-8を使用しているとまだ信じているなら、それをどのように証明しましたか?ところで、getBytes()の問題は関数が非常に古く、UTF-8がまだサポートされていないときにバージョン1.1に既に存在していたので、UTF-8を使用することは実際には予測できません。 –

-1

文字のSIZEは、charに必要な記憶領域で、16ビットです。文字列の長さ(基本となる文字配列またはバイト配列の長さも)は、ビット数ではなく、文字数(またはバイト数)です。

だからこそ、サイズは8で除算したが、長さは除外した。長さに2を掛ける必要があります。

また、別のエンコーディングを指定した場合は、バイト配列の長さが異なります。この場合、getBytes()を実行するときに、単一または可変サイズのエンコーディングへの変換が実行されました。

参照:http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes(java.nio.charset.Charset

+0

いいえ、彼は 'getBytes()'を使っていましたので、実際にはバイト数です(驚くべきことではありません)。 –

+0

はいこの回答はちょっとした話題であり、質問を誤解しています...私は更新を提案します。 – jayunit100

2
私は私が間違っているなら、私を修正しますが、あなたが唯一の1つの文字を持っているように正しく、それは1として表示される文字列の長さを見つけて、私は何を考えて言いたい

文字列に長さはサイズではなく長さを示します。長さとサイズは2つの異なるものです。 ..あなたは、あなたがchar型の配列の1つの文字が2バイトの大きさを持っており、あなたの文字列が含まれていることが1文字の長さであることを持って、間違った方法も

0

に占めるバイト数を

チェックこのLinkを見つけています1バイトのサイズではありません。 Javaで

Stringオブジェクトで構成されています

private final char value[]; 
private final int offset; 
private final int count; 
private int hash; 

これだけはとにかくStringオブジェクトがchar配列その後、大きいことを保証すべきです。 オブジェクトのサイズの詳細については、char配列のオブジェクトヘッダーと多重度の要素も参照できます。例えば、hereまたはhereです。

+0

これは、あなたが文法を改善しようとすることはできません...など? – jayunit100

0

私が最初にして、説明のビットいくつかのコードを追加したい:だから、あなたが実際に不足していること、であるあなたが提供されていない

Character size: 2 
String size: 4 
feff061 

import java.nio.charset.Charset; 

public class Main { 

    public static void main(String[] args) { 
     System.out.println("Character size: " + Character.SIZE/8); 
     final byte[] bytes = "a".getBytes(Charset.forName("UTF-16")); 
     System.out.println("String size: " + bytes.length); 
     sprintByteAsHex(bytes[0]); 
     sprintByteAsHex(bytes[1]); 
     sprintByteAsHex(bytes[2]); 
     sprintByteAsHex(bytes[3]); 
    } 

    static void sprintByteAsHex(byte b) { 
     System.out.print((Integer.toHexString((b & 0xFF)))); 
    } 
} 

を、出力がされますgetBytesメソッドへの任意のパラメータ。おそらく、文字 'a'のUTF-8表現のバイトを取得しています。

UTF-16を要求したときに、なぜ4バイトが得られたのですか? Javaは内部的にUTF-16を使用していますが、2バイトは正しく取得していますか?あなたは出力を調べると

は:

feff061 

Javaは、実際に私たちにBOMを返さ:https://en.wikipedia.org/wiki/Byte_order_mark

最初の2バイト:feffは、後続のバイトがUTF-16ビッグエンディアンになることを通知するために必要です。詳細については、Wikipediaのページを参照してください。

残りの2バイト:0061は、文字「a」の2バイト表現です。 http://www.fileformat.info/info/unicode/char/0061/index.htm

したがって、Javaの文字は2バイトですが、特定のエンコーディングを持たないバイトを要求すると、さまざまなエンコーディングがさまざまなバイト数を必要とするため、常に2バイトを取得するとは限りません。文字。