2013-03-27 7 views
17

私はいくつかの時間を弱参照を使用することから利益を得ることができるいくつかの動作を実装しています。私は、クラスのユーザーが、これがそうであるかどうかを構築時に示すことができるようにしたいと思います。 WeakReferenceが、私が(これは私が実際に何をしようとしているモックアップ、ではない)のような何かを行うことができ思える一見Referenceを拡張しているので:StrongReferenceオブジェクトがないのはなぜですか?

public class Container<T> { 
    private boolean useWeakRef; 
    private Reference<T> ref; 

    public Container(boolean isWeak) { 
     useWeakRef = isWeak; 
    } 

    public void store(T val) { 
     if(useWeakRef) { 
      ref = new WeakReference<>(val); 
     } else { 
      ref = new StrongReference<>(val); 
     } 
    } 

    // May return null 
    public T get() { 
     return ref.get(); 
    } 
} 

をしかしそこにはStrongReferenceクラスがありません、とによりますReference javadocs

参照オブジェクトはガベージコレクタと緊密に連携して実装されるため、このクラスを直接サブクラス化することはできません。

したがって、オブジェクトに対する強い(つまり通常の)参照を保持する独自のサブクラスの参照を作成することはできません。これは、呼び出し元から弱い(または柔らかい)参照を使用するかどうかを隠すクラスを作成することはできないことを意味しているようです。

なぜこのクラスが存在しないのか分かりません。StrongReferenceオブジェクトは、clear()が呼び出されていない限り、get()からオブジェクトを返すだけです。なぜこれが行方不明ですか? StrongReferenceは何らかの形でReferenceと矛盾していますか?一般的な参照ホルダオブジェクトを構築するのがずっと簡単になります。

+0

本当に必要な場合は、その機能のインターフェイスを実装するのも簡単です。 –

+1

はい、私は回避策があることを認識していますが、Java設計者がこの一見論理的なクラスを意図的に避けていると想定しています。 – dimo414

+0

+1。また、強力でスレッドセーフな参照であるAtomicReferenceもありますが、同じインタフェースを実装していません。 – Thilo

答えて

1

グアバのLocalCacheは、StrongReferenceクラスにしたいものを複製するStrongValueReferenceクラスを使用します。 Guavaはこれを公開クラスとして公開していませんが、これはJDKの欠落している機能であることを確認し、必要なときに複製することは問題ありません。

と言いますが、実際に使用している参照の種類を抽象化する必要があるほとんどの使用例では、おそらくGuava's Cacheの動作をそのまま使用することができます。私は、この抽象的な参照動作を再考する前に、Guavaの既存のキャッシング・メカニズムを探索するために、

3

パブリック/保護されたコンストラクタがないため、参照のサブクラス化はできません。しかし、回避策があります:

class StrongReference<T> extends WeakReference<T> { 
    private final T referent; 

    StrongReference(T referent) { 
     super(null); 
     this.referent = referent; 
    } 

    @Override 
    public T get() { 
     return referent; 
    } 

    // implement other methods 
} 
+4

それは私には非常にハックに見えます。継承は "is a"の関係を表しており、 'StrongReference'が" WeakReference "であると主張するのは難しいでしょう:) – creinig

+0

私が使用していた実装(私がGuavaに切り替える前)は、オブジェクトの構築方法に応じて 'WeakReference 'または 'T'を直接保持し、' get() 'を実装したラッパー' StrongOrWeakReference ' 'clear()' – dimo414

+1

@creinig:私は確かに、強い参照は弱い参照のスーパーセットであることは確かです。弱い参照のようにオブジェクトを見つけることができるだけでなく、オブジェクトを生きたままにしたり、ガベージコレクションを防ぐことができます。 –

4

私はこれを行うために必要としたら、私はちょうどカスタムリファレンス・インターフェースと弱い参照の些細なサブクラスを作成しました。それは迷惑ですが、それはあなたができるほど良いものです。

public interface MyReference<T> { 
    public T get(); 
} 

public class MyWeakReference<T> extends WeakReference<T> implements MyReference<T> { 
} 

public class MyStrongReference<T> implements MyReference<T> { 
    // obvious implementation here ... 
} 

UPDATE:

は、私はこれが最初の場所でJDK(私は、あまりにも、それはされていた希望)に含まれていなかった理由が、しかし、私は感じないアイデアを持っていない、明確にしますこれは妥当な回避策です。

この考えを正当化しようとしている人には、参照の強さがキャッシュの設定の一部であるカスタムキャッシュを実装する必要があることがわかりました。

+0

これは質問に答えません。質問は、Java開発者がこれを実装していない理由を質問しています。 –

+2

@StephenC - それは疑問の一部です。 「これは呼び出し元からの弱い(または柔らかい)参照を使用するかどうかを隠すクラスを作ることは不可能であると思われる」と思われる部分は、問題の「解決策」の欲求を暗示しているようです。 – jtahlborn

関連する問題