2

重複の可能性:
Javaでのnull文字列の連結

コードスニペットの下を見つけてください

String str = null;
str = str + "hi";

System.out.println(str)

上記のコードの出力はですnullhi

出力はそうなると思っていたhiので、出力にちょっと驚いて、その背後にある理由を見つけることができませんでした。

誰か説明してもらえますか?

4

6 に答える 6

4

これはappendメソッドだからです。+いずれかStringBuilderまたはStringBuffer追加操作として変換されます。

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";

public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

以下は、プログラム用に生成されたバイトコードです

 0  aconst_null
 1  astore_1 [str]
 2  new java.lang.StringBuilder [16]
 5  dup
 6  aload_1 [str]
 7  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [18]
10  invokespecial java.lang.StringBuilder(java.lang.String) [24]
13  ldc <String "hi"> [27]
15  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [29]
18  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [33]
21  astore_1 [str]
22  getstatic java.lang.System.out : java.io.PrintStream [37]
25  aload_1 [str]
26  invokevirtual java.io.PrintStream.println(java.lang.String) : void [43]
29  return

したがって、コードは実際にに変換されappend(null)、そのappend("hi")ような出力が得られるのはそのためです。

また、それは明確に文書化されています15.18.1. String Concatenation Operator +

実装では、中間のStringオブジェクトの作成と破棄を回避するために、変換と連結を1つのステップで実行することを選択できます。繰り返される文字列連結のパフォーマンスを向上させるために、JavaコンパイラはStringBufferクラスまたは同様の手法を使用して、式の評価によって作成される中間Stringオブジェクトの数を減らすことができます。

于 2012-10-30T18:08:55.460 に答える
3

JLSから。

http://docs.oracle.com/javase/specs/jls/se7/html/index.html

§15.18.1。文字列連結演算子+参照

1つのオペランド式のみがString型である場合、実行時に文字列を生成するために、もう1つのオペランドで文字列変換(§5.1.11)が実行されます。

§5.1.11。文字列変換参照

参照がnullの場合、文字列「null」(4つのASCII文字n、u、l、l)に変換されます。

于 2012-10-30T18:11:44.037 に答える
1

nulljavaでnull参照を出力しようとした場合に出力される値です。

于 2012-10-30T18:09:12.717 に答える
1

すべての文字列ではない値を連結すると、変換されない値は、のように変換されString.valueOfます。 String.valueOf(null)文字列"null"です。

于 2012-10-30T18:09:28.077 に答える
0

これは、Javaの作成者が早い段階で下した決定でした。文字列に連結されたnull値は、として出力されnullます。ログメッセージを出力しようとしていると想像する場合、この種の意味があります。

String personName = null;
System.out.println("Person name is: " + personName);

結果:

人名は:null

この動作は、変数が実際にはnullであることがわかっているため(たとえば、空の文字列ではなく)、デバッグ時に役立ちます。

あなたがこれを行おうとしたときに彼らは単に例外をスローすることを選択できたかもしれませんが、それはログメッセージや例外文字列を作成するようなことをしているときでさえ多くのことを壊してしまうでしょう。

また、期待どおりに実行し、null値を空の文字列として出力するようにすることもできます。これは、.NETFrameworkが行うことです。しかし、最終的には、それは彼らがやろうと決心したことではありません。

于 2012-10-30T18:09:28.000 に答える
0

あなたが示した例では、文字列nullをhiと連結しているため、生成される出力は
nullhiです。

String str = null;
str = str + "hi";

System.out.println(str);


as str=str+"hi "//shows one string is concatenating with the other

したがって、得られる出力は正しいです。

于 2012-10-30T18:20:40.097 に答える