2013-10-01 14 views
5

ほとんどのシングルトンクラスと同様に、プライベートコンストラクタでクラスを「拡張する」標準的なテクニックはありますか?具体的には、java.lang.management.ThreadInfoクラスを拡張しようとしています。これは、一意性を制御するためにHashSetに多くを追加するためです。しかし、2つのスレッドが等しいかどうかを判断する方法は、equals()メソッドのデフォルトの実装とは異なり、同じではありません。プライベートコンストラクタでクラスを拡張するためのテクニック

この場合、クラスの拡張は明らかにオプションではありません。

コンストラクタでThreadInfoを受け入れ、その後、手動で値を使用して、関連するすべてのフィールドを移入するラッパークラスのようなものを作ることが合理的である、そしてequals()hashCode()を上書きし、またはこれを行うには良い方法はありますか?このような

何かが私が書くために始めているものですが、より良い実装が理想的である:

class ThreadInfoWrapper { 

    private ThreadInfo info; 
    ThreadInfoWrapper(ThreadInfo info) { 
     this.info = info; 
    } 

    //Populate instance variables with Thread.State, thread ID, etc.. with 
    //Getters/setters and all that other stuff 

    public boolean equals(Object o) { //Unique implementation 
    } 

    public int hashCode() { //Whatever implementation 
    } 

} 

しかし、これは、いくつかの基本的な機能を達成するための非常に遠回りのように感じています。 Javaの標準ライブラリにカスタムコンパレータを使用したセットの実装が存在しません。私は自分のハッシュセット実装を書くことができると思いますが、それは簡単な状況ではあまりにも多くの作業です。どんな洞察も役に立つでしょう。

+0

私はこのようなクラスを拡張することはできません。 –

+0

@JakobWeisblat実際には、それらは拡張することができますが、この状況では役に立たない内部クラスによってのみ拡張できます。自分のクラスファイルでそれらを拡張することはできません。私は妥当な選択肢を探していて、特に標準的なプラクティスがあるかどうかを確認しています。私はちょっと探した後に何も見つかりませんでした。その後、 – Kon

+0

幸運。 –

答えて

2

拡張すると、プライベートコンストラクタをスーパークラスコンストラクタとして使用する派生クラスを作成する方法を意味します。あなたはそうすることができないように非公開にされています。有能なプログラマーによってJREクラスが作成されたので、これには十分な理由があります。したがって、たとえリフレクションやバイトコード操作などのトリッキーを使用して回避することができたとしても、そうしないでください。

しかし、すべてが失われることはありません。とにかく、継承の構成を好むべきです。デコレータとプロキシのデザインパターンは便利です(あなたの例はこれに近いです)。

1

他にもいくつかのオプションがあるとしたら、あなたがやっていることは合理的だと思います。

代わりに、デフォルトの代わりに "特別な"等価を使用するHashMapの独自のサブクラスを書くこともできます。 (すでにこれを行うにはApacheやグアバの実装があるかもしれません - 誰もがぶっきらぼうを知っていますか?)

(後で追加)

私は怠け者だから、それが公開するかなり「安全」ですのでThreadInfoには、すべてのゲッターを持っているので、 、私はゲッターやセッターなしで、ラッパークラスは非常に単純にするために誘惑されるだろう:

public class ThreadInfoWrapper { 

// public so an outsider can get at the wrapped ThreadInfo 
// could be private if you are sure that will never be necessary 
public final ThreadInfo threadInfo; 

public ThreadInfoWrapper(ThreadInfo threadInfo) { 
    this.threadInfo = threadInfo; 
} 

public boolean equals(Object o) { //Unique implementation 
    // refer to threadInfo.blah... 
} 

public int hashCode() { //Whatever implementation 
    // refer to threadInfo.blah... 
} 

}

しかし、これはあなたのequalsとhashCodeのために使用されているだけで何の情報に依存します。

+0

応答をありがとう。私が検索していたとき、私はこの応答(http://stackoverflow.com/questions/14880450/java-hashset-with-a-custom-equality-criteria)がGuavaがSetの実装を「特に拒否した」と主張していました'equals()'メソッドと互換性のない等価性基準を持つ。 – Kon

+0

あなたの研究をしたような音。がんばろう。 – user949300

関連する問題