4

これは、次のような Java コードに関する質問です。

List<String> list = new ArrayList<String>() {{add("hello"); add("goodbye");}}

プログラマーは、インスタンス初期化ブロックに押し込むためだけに、匿名で ArrayList を拡張しました。

問題は、プログラマーの唯一の意図が単に以下と同じことを達成することである場合です。

List<String> list = new ArrayList<String>();
list.add("hello");
list.add("goodbye");    

それでは、最初の方法でそれを行うことの意図しない結果は何ですか?

4

4 に答える 4

15

そのようなコードを実行することの危険性は (一般的な場合)、equals()メソッドを壊す可能性があることです。これは、次の 2 つの一般的なテンプレートがあるためですequals()

public boolean equals(Object ob) {
  if (!(ob instanceof MyClass)) return false;
  ...
}

public boolean equals(Object ob) {
  if (ob.getClass() != getClass()) return false;
  ...
}

最初のものは、あなたが話している匿名サブクラスで引き続き機能しますが、2 番目のものは機能しません。つまり、 instanceof は必ずしも可換ではないため、2 番目の方法がベスト プラクティスと見なされます(意味a.equals(b)は equal ではない可能性がありb.equals(a)ます)。

ただし、具体的には、この場合、他のオブジェクトがインターフェイスであることを確認するだけArrayListのメソッドを使用するため、問題ありません。AbstractList.equals()instanceofList

しかし、それは知っておくべきことです。

私が提案するのは、少し異なる方法で行うことです。

List<String> list = new ArrayList<String>(
    Arrays.asList("hello", "goodbye")
);

確かに冗長ですが、結果として得られるクラスは "pure" であるため、この方法で問題が発生する可能性は低くなりますArrayList

于 2009-03-22T21:40:43.843 に答える
5

ここでの大きな問題は、周囲のクラスの内部クラスを作成していることだと思います。作成するリストには、外部クラスへの暗黙的なthis参照が含まれます。

通常、これは問題ではありません。ただし、このオブジェクトをシリアル化すると (私はこれに遭遇したので、特にXStreamを使用することを考えています)、シリアル化されたフォームにはシリアル化された外部クラスが含まれます。これはあなたが通常期待するものではなく、奇妙な動作を引き起こす可能性があります!

上記の初期化パターンをよく使用します。内部クラスのメカニズムを認識している限り、問題はありません。ところで。等価性の問題は、派生物に対する等価性の実装全般の問題ではないと思います。

于 2009-03-23T09:03:13.890 に答える
2

コードのパフォーマンスやメモリへの影響はごくわずかです(測定可能な場合でも)。

ここでの本当のヒットは、「この男は何をしているのか」と考えるために、たとえビートであっても、人々を止めさせているということです。

コードを読んでいる間に1,000回それをしなければならない場合、パフォーマンスの問題があります。

コードは、すべてのパフォーマンス、完全性、および標準の要件が満たされている限り、読みやすいものでなければなりません。

ほとんどの場合、あなたはあなたのコードを維持する人になるでしょう。あなたの将来の自分に優しくして、コードをできるだけ読みやすくしてください。あなたがそのようないくつかの派手なschmancyのことをするつもりなら、正当な理由があり、それをコードで文書化してください。唯一の理由がプログラマーとしてあなたのチョップを誇示することであるならば、あなたはプログラマーの本当の仕事に失敗しました:困難を簡単にすること。

于 2009-03-23T10:32:35.720 に答える
0

最初のアプローチもパフォーマンスに悪影響を及ぼします。多くの匿名クラスでメモリが乱雑になるのは良くありません。また、起動が遅くなります。

于 2009-03-22T22:23:41.697 に答える