2017-09-08 6 views
-1

スーパークラスがコンストラクタ内の巨大なオブジェクトを読み込んで(たくさんの構文解析を行い)そこから値を初期化するクラスがあります。サブクラスでは、その巨大なオブジェクトから2番目の値が必要です。私はファイルを2回解析したくないので、もはや必要ではないので、オブジェクトの存続時間のために解析結果をメモリに残したくない。スーパークラスのコンストラクタから巨大なオブジェクトを渡す方法

私は何をしたいことは(Javaでことはできません)、次のようになります。

私は書くことができますが、Superclassを直接使用する場合は、hugeを削除しません、それがどうなるか
public class Superclass { 
    private Object foo; 

    public Superclass() { 
     HugeObject huge = getHugeObject(); 
     this.foo = huge.getFoo(); 
     return huge; // “huge” gets garbage collected if not used 
    } 
} 

public class Subclass extends Superclass { 
    private Object bar; 

    public Subclass() { 
     HugeObject huge = super(); 
     this.bar = huge.getBar(); // “huge” gets garbage collected, too 
    } 
} 

public class Superclass { 
    protected HugeObject huge; // to pass the huge object to subclass 
    private Object foo; 

    public Superclass() { 
     this.huge = getHugeObject(); 
     this.foo = this.huge.getFoo(); 
     // this.huge = null; // “huge” NOT garbage collected (would cause NPE in Subclass) 
    } 
} 

public class Subclass extends Superclass { 
    private Object bar; 

    public Subclass() { 
     this.bar = super.huge.getBar(); 
     super.huge = null; // “huge” gets garbage collected only when Subclass used 
    } 
} 

実際、この問題は一般的にOOプログラミングに直観的ではないようです。 huge = null;Superclassという方法で書くことができるので、オブジェクトは削除されます早くしかし、それは良いスタイルのように感じません。これをより良く解決するJava/OOのアプローチの考え方はありますか?すべてのサブクラスのコンストラクタが実行された後に実行できる「ポストコンストラクタ」のようなものがありますか?何かのように

public Superclass() { 
    this.huge = getHugeObject(); 
    this.foo = this.huge.getFoo(); 
} finally /* executes after subclass constructor has finished */ { 
    this.huge = null; 
} 

コールバックを使用していますか?あなたが複数のインスタンスのためにそれを再利用したい場合は

+1

おそらく、(シングルトンや@Component) 'Superclass'で解析を行い、実際に必要なものを抽出して保存します(巨大なものは保存しません)。次に抽出された値を他の場所で使用してください。 –

+1

あなたの質問は[X/Y問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。正しい解決法ではないような、解決策の助けを求める代わりに、解決しようとしている問題を教えてください。 –

+0

私は、一見すると、これに対処するための適切なパターンを探していました。実際にはこれは私のプログラムが行うもので、解決策はありませんでした(単純に「巨大」を維持し、JVMヒープを増やしました。これは私が探していた「解決策」の種類ではありません)。実際、@ OldCurmudgeonは私に絶対に正しいOOソリューションを教えてくれました。 – Paramaeleon

答えて

0

私はおそらく一種のコールバックを使用します。

public class Superclass { 
    private Object foo; 

    public Superclass() { 
     HugeObject huge = getHugeObject(); 
     gotHugeObject(huge); 
    } 

    /* 
    * NB: Called during construction! Beware of leaking `this` etc.!!! 
    */ 
    protected void gotHugeObject(HugeObject huge) { 
     this.foo = huge.getFoo(); 
    } 
} 

public class Subclass extends Superclass { 
    private Object bar; 

    /* 
    * NB: Called during construction! Beware of leaking `this` etc.!!! 
    */ 
    @Override 
    protected void gotHugeObject(HugeObject huge) { 
     super.gotHugeObject(huge); 
     this.bar = huge.getBar(); // “huge” gets garbage collected, too 

    } 
} 

このようにするには注意が必要です。主に、この時点で対象物が建設中であるため、曖昧な問題の原因となる可能性があるのは、thisの漏洩の危険性があります。

しかし、何が起こっているのかが簡単で明確であり、私にはそうしたコメントを少しでも緩和できるので、最も明確な選択肢になります。

+2

Downvote ??なぜどんなアイデア? – OldCurmudgeon

-1

は、その後、おそらくコンストラクタにHugeObjectを渡す方が良いです:

public Superclass(HugeObject huge) { 
     this.huge = huge; 
     this.foo = this.huge.getFoo(); 
     // this.huge = null; // “huge” NOT garbage collected (would cause NPE in Subclass) 
    } 

は今、あなたはHugeObject一生の制御である

HugeObject huge = /* initiate */; 
new SuperClass(huge); 
new SubClass(huge); 
関連する問題