2010-12-14 3 views
2

スーパークラスのプライベートメソッドをJavaで "オーバーライド"することは可能ですか?Java Reflect/AOPスーパータイププライベートメソッド

私がオーバーライドしたいクラスのクラスはサードパーティクラスなので、ソースを変更することはできません。リフレクティブにクラスにメソッドを設定する方法があれば理想的です。

また、第三者クラスのプライベートメソッドをインターセプトすることが可能な場合は、これが適切です。

+0

バイトコードの可視性を変更するために、バイトコード(dis)アセンブラを使用してこれを行うことができます。ああ、それはとても厄介です! –

+0

サウンドは価値がある。 :) – Finbarr

+0

私はあなたが_AOP_のメソッドインターセプタを使って、通常の 'proceed()'に代理するのではなく、reflectionメソッドを使ってメソッドインスタンスを作成し、 'setAccessible() 'true'としてください – mickeymoon

答えて

2

Javaのスーパークラスのプライベートメソッドをすべてオーバーライドすることは可能ですか?

私は微調整があるだろうリフレクションを使用しないと思う、それはあなたがこれを行うための法的な方法はありませんがOOP

3

を中断します。しかし、私はあなたに次のソリューションを提案することができます。

  1. 本当にこのメソッドをオーバーライドしますか?他の解決策について考えてみてください。
  2. Javaはコンパイル時にのみアクセス許可をチェックします。びっくりした?私はこの事実を知るのにとても驚きました。したがって、サードパーティクラスのスケルトンを作成することができます(空の実装でも)。興味深い方法は、privateの代わりにprotectedにする必要があります。今度はあなたのサブクラスを書いて、あなたのスタブに対してコンパイルしてください。次に、あなたのサブクラスだけをパッケージ化し、 "本当の"クラスで実行しようとします。それは動作するはずです。私は継承でこのトリックを試していませんが、プライベートメソッドまたはフィールドにアクセスしなければならないときに試してみました。
  3. クラスをラップしてその実装を変更する動的プロキシを使用してみてください。私はあなたが何を正確にしているのか分からないので、あなたが本当にこの方法を使うことができるかどうかはわかりません。しかし、あなたができることを願っています。 #1または#2に戻っていない場合。
+0

check http://stackoverflow.com/questions/12817502/accesing-private-methods-in-java –

4

はい。あなたはaspectjでそれをすることができます。真のオーバーライドではありませんが、結果はそうです。

ここではスーパークラスです。

public class MySuperClass { 

    private void content(String text) { 
     System.out.print("I'm super " + text); 
    } 

    public void echo() { 
     content("!"); 
    }   
} 

同様の方法を含むインターフェイスを作成します。

public interface Content { 
    void safeContent(String text); 
} 

スーパークラスに強制的にそのインターフェイスを実装させ、それを呼び出すためのaround adviceを追加するアスペクトを作成します。

public privileged aspect SuperClassAspect { 

    void around(MySuperClass obj) 
      : execution(* content(String)) && target(obj) { 

     Object[] args = thisJoinPoint.getArgs(); 
     ((Content) obj).safeContent((String) args[0]); 
    } 

    // compiler requires 
    public void MySuperClass.safeContent(String text) {} 


    declare parents :MySuperClass implements Content; 
} 

superを拡張し、そのインターフェイスを実装する子クラスを作成します。

public class Overrider extends MySuperClass implements Content { 

    public void safeContent(String text) { 
     System.out.print("Not that super " + text); 
    } 
} 

オーバーライドオブジェクトを作成してエコーメソッドを呼び出すと、オーバーライドセーフコンテンツの出力が表示されます。

+0

このアプローチはうまくいきますが、単純にしておき、' around() 'アドバイスを'MySuperClass +'、目的の呼び出しや実行を傍受し、適切に修正された結果を返しますか?私はここでITDを使うのはおそらく不必要だと思います。 – kriegaex

+0

これは単純化することができますが、私の指摘はこれをオーバーライドのように感じさせることでした。 –

0

はい、可能ですが、それはSOLIDの原則の1つに矛盾するので、実行しないでください。より正確には、それはLiskov substitution principleと矛盾します。

注 Q(x)は次に、Q(Y) 型TのオブジェクトXについて証明可能性とすること型Sのオブジェクトyに対する証明可能であるべきで、SはT.

のサブタイプであります

つまり、プライベートメソッドはオブジェクトのプロパティなので、継承された型のオブジェクトは同じプロパティを持つ必要があります。メソッドのスローも同じです。

のためJavaが制限しています。

関連する問題