2

PMD の規則の背後にある「理由」という既存のスレッドの行に沿って、特定の PMD 規則の意味を理解しようとしています: String および StringBuffer Rules.StringInstantiation

この規則は、String オブジェクトを明示的にインスタンス化してはならないことを示しています。マニュアルページによると:

String オブジェクトのインスタンス化は避けてください。これらは不変であり、安全に共有できるため、通常は不要です。

このルールは、次の Java クラスによって定義されます:net.sourceforge.pmd.lang.java.rule.strings.StringInstantiationRule

例:

private String bar = new String("bar"); // String bar = "bar"; を実行するだけです。

http://pmd.sourceforge.net/pmd-5.0.1/rules/java/strings.html

無意味であることを除けば、この構文がどのように問題なのかわかりません。全体のパフォーマンスに影響はありますか?

ご意見ありがとうございます。

4

6 に答える 6

3

PermGenString foo = "foo"空間に "foo" のインスタンスが存在します (これはstring interningと呼ばれます)。後で入力String bar = "foo"すると、PermGen スペースには「foo」が 1 つしかありません。

書き込みは、ヒープに対してカウントString foo = new String( "foo" )するオブジェクトも作成します。String

したがって、メモリの浪費を防ぐためのルールがあります。

乾杯、

于 2013-01-02T14:16:08.427 に答える
3

通常、測定可能な方法でパフォーマンスに影響を与えることはありませんが、次のようになります。

private String bar = new String("bar"); // just do a String bar = "bar";

この行を100万回実行すると、100万個のオブジェクトが作成されます

private String bar = "bar"; // just do a String bar = "bar";

この行を 100 万回実行すると、1 つのオブジェクトが作成されます。

それが実際に違いを生むシナリオがあります。

于 2013-01-02T14:16:47.070 に答える
3

全体のパフォーマンスに影響はありますか?

さて、パフォーマンスとメンテナンス。無意味なことをすると、読者はそもそもなぜそのコードがあるのか​​不思議に思うでしょう。その無意味な操作に新しいオブジェクト (この場合は 2 つ - newと new ) の作成含まれる場合、それを避けるもう 1 つの理由です...char[]String

以前は、既存の文字列がもともと長い文字列の小さな部分文字列として取得された場合、または大きな文字配列に裏打ちされた文字列を取得する他の方法である場合に呼び出す理由がありました。new String(existingString)Java の最近の実装ではそうではないと思いますが、古いものを引き続き使用できることは明らかです。とにかく、これは定数文字列の問題ではありません。

(新しいオブジェクトを作成すると、それを同期できると主張することができます。ただし、最初から文字列で同期することは避けたいと思います。)

于 2013-01-02T14:16:56.750 に答える
2

これは、新しいIDを作成し、場合によってはオブジェクトIDがアプリケーションにとって重要/重要であるため便利です。たとえば、内部番兵の値として使用できます。他にも有効なユースケースがあります。たとえば、定数式を避けるためです。

初心者がそのようなコードを書く場合、それは間違いである可能性が非常に高いです。しかし、それは非常に短い学習期間です。中程度の経験を積んだJavaプログラマーが誤ってそれを書く可能性はほとんどありません。それは特定の目的のためでなければなりません。「ばかげた間違いのように見えますが、作るのに手間がかかるので、おそらく意図されたものです」の下に提出してください。

于 2013-01-02T14:37:17.770 に答える
2

1 つの違いは、メモリ フットプリントです。

String a = "abc"; //one object
String b = "abc"; //same object (i.e. a == b) => still one object in memory
String c = new String("abc"); // This is a new object - now 2 objects in memory

正直なところ、私が考えることができる唯一の理由は、元の文字列のビューである部分文字列と組み合わせて String コンストラクターを使用する理由です。その場合に String コンストラクターを使用すると、元の文字列が不要になった場合に、元の文字列を取り除くのに役立ちます。

ただし、Java 7u6 以降、これはもはや当てはまらないため、これ以上使用する理由はありません。

于 2013-01-02T14:16:32.203 に答える
1

それは

  • 無意味
  • 紛らわしい
  • 少し遅い

できる限り単純でわかりやすいコードを書くようにしてください。無意味なコードを追加することは、全体的に悪いことです。

于 2013-01-02T14:22:40.857 に答える