2

java.lang.String2つの作成方法が存在する唯一のクラスはなぜですか。

new1)「 」キーワードを使用した通常の方法。

String s = new String("abc");

2)リテラル付き(クラスStringでのみ使用可能)String

String s = "abc";

では、なぜString他のクラスのリテラルがあり、リテラルがないのですか?

4

10 に答える 10

10

言語設計者がそのように感じたので、短い答え。

Stringは非常に一般的なクラスなので、例外があります。他にも同様の例外がいくつかあると確信しています(Tom Hawtinsのコメントを参照)

于 2009-09-10T12:08:01.470 に答える
5

オートボクシング(IMOはカウントされません-リテラルはクラスではなくプリミティブ型用です。ラッパークラスへの暗黙の変換があります)は別として、String(String)コンストラクターは実際に便利です。文字データのコピーを取ります。つまり、元の文字列が小さいがバッキングが大きいchar[]場合、新しい文字列はそれから独立しています。

これは、たとえばファイルから短い行を読み取る場合に重要になる可能性があります。

文字列リテラルがある理由については、便利だからです。代わりに何を持っていますか?開発者に以下を使用するように強制しますか?

String x = new String(new char[] { 'h', 'e', 'l', 'l', 'o' });

同時にインターンを取得しませんか?

他にどのクラスのリテラルが必要ですか?おそらく、マップとリストのリテラルが役立つでしょう-それらがJava7で提供されているかどうかは思い出せません。配列初期化子は、オブジェクト初期化の省略形であるという点で、「リテラルに少し似ている」と考えることができます。

于 2009-09-10T12:13:41.140 に答える
3

文字列は基本的なデータ型であり、プリミティブと同じレベルであると見なされているためだと思います。

ところで、

new String("abc");

実際には2つの文字列を作成します。

  1. あなたが参照を失うインターンされたもの
  2. 同じコンテンツの新しいインスタンス

個人的には、Stringのコンストラクターを使用する必要はありません。

于 2009-09-10T12:15:38.250 に答える
2

文字列は、通常のクラスですが、プログラミングの基本要素の1つを表します(他の要素は数値とブール値です)。したがって、Javaは、Stringオブジェクトを初日から半プリミティブ変数と見なし、これを許可しました。

後で、自動ボクシングが標準コンパイラの一部になったときに、この方法で数値ラッパーオブジェクトを作成することもできます。

Integer i = 123;

TomHawtin-tacklineが質問へのコメントで言及しているように。

于 2009-09-10T12:11:47.697 に答える
1

リテラルを持つオブジェクトタイプは、 Stringsnull、およびクラスリテラルです。

配列にイニシャライザーを使用することも可能です。イニシャライザーとして使用する場合は、プリミティブリテラルを使用してオブジェクトを作成することもできます。これは、真のリテラルではなく、単純な構文で「2つの作成方法」に適合します(値の初期化にのみ使用できます)。オブジェクト式が発生する可能性のあるすべての場所よりも)。

シリアル化やリフレクションなどの他の手法を使用すると、「2つの作成方法」を破ることもできます。

于 2009-09-10T12:22:23.960 に答える
1

もちろん、すべてのプリミティブ数値型のリテラル、ブール値のtrueとfalse、およびcharsもあります。あなたの質問で、技術的に「他のクラスのリテラルはありません」と答えたと思います。わかった。「null」はリテラルオブジェクトであると誰かが指摘したと思うので、あなたのステートメントは技術的に不正確ですが、それが他の唯一の例だと思います。

しかし、次の明らかな質問は、他にどのクラスのリテラルを使用したいのかということです。言語を設計している場合、BufferedReaderリテラルはどのようになりますか?またはResultSetリテラル?またはJCheckBox?

理論的には、たとえば、「ファイルリテラル」は、「$ / home / bob /myfile.txt$」などの特別な区切り文字で囲まれたファイル名であると言えます。しかし、誰かが「JButtonはどうですか」と言うことができます。ボタンのテキストと、ボタンが起動するActionListenerと、「%Submit、SubmitListener%」のような適切な区切り文字を使用して、そのようなリテラルを作成できませんでした。次に、Socketsについては、ホスト名を特別な区切り文字などに入れることができませんでした。区切り文字として使用する句読点がすぐになくなることは明らかだと思います。したがって、File( "/ home / bob / myfile.txt")やSocket( "www.example.com"、631)のように、話しているクラスを識別するために何らかのテキストを書く必要があります。 )。しかし、それはコンストラクターに非常によく似ています。

値の性質によって純粋に表現できる(たとえば、すべての数字が数値のリテラルになる)または句読点を使用して表現できる「もの」の数は、キーボードに適切に収まる句読点の数によってかなり制限されます。そして、あなたが話したいと思うかもしれないすべての異なる種類のもののために600の特別なアイコンを備えたキーボードが欲しいですか?言葉はとても簡単で柔軟性があります。

文字列は非常に一般的に使用されており、代替手段は非常に扱いにくいため、特別な場合にするのが理にかなっています。

于 2009-09-10T13:25:52.837 に答える
1

Java 7は、配列リテラルによく似たリテラルを介してコレクションを初期化する機能を提供する予定です。

于 2009-09-10T15:58:34.973 に答える
0

最後に確認しました:

Integer wInt = 1;

正常に動作します。

于 2009-09-10T12:08:45.663 に答える
0

後者の形式の作成には、文字列のインターンも含まれます。つまり、コードがある場合:

String s = "abc";
String t = "abc";

コンパイラはこれを最適化し、同じStringオブジェクトへの2つの参照を取得します。(s == tは真になります)。

文字列インターンは、文字列式でも機能します。

于 2009-09-10T12:17:16.950 に答える
0

文字列リテラルは、(Cでの)優先順位と構文が確立された便利なショートカットです。Java設計者がC++プログラマーを誘惑したい場合は、文字列リテラルがそこになければなりませんでした。幸い、文字列の処理は、C++よりもJavaの方がはるかに賢明です。

他の標準オブジェクトには事実上の構文がありませんでした-マップリテラルをどのように記述しますか?

于 2009-09-10T13:35:54.090 に答える