私は、Javaで動的な型定義を持つ簡単な解釈言語を実装しました。残念ながら私は以下の問題に遭遇しました。次のコードをテストする場合:Javaでの言語の解釈とJavaのメソッドへの呼び出し
def main() {
def ks = Map[[1, 2]].keySet();
return ks.size();
}
を私は次の例外つまずい:もちろん
java.lang.IllegalAccessException: class is not public: java.util.HashMap$KeySet.size()int/invokeSpecial
をこれが真実であるとのHashMap $キーセットクラスは、「パッケージ」の可視性を持っているという事実によって引き起こされます。つまり、私が "size()"メソッドを呼び出すと、コードから見えないクラスのメソッドを呼び出します。 Javaはこの問題を簡単に回避します。keySet()メソッドはSet型の値を返します。したがって、使用されるメソッドsize()はパブリッククラスと抽象クラス "Set"で宣言されます。
私の質問です:どのようにこれは一般的な方法で処理する必要がありますアイデアを持っていますか?
interface I1 {
public void foo();
}
interface I2 {
public void foo();
}
interface I3 {
public void foo();
}
class C implements I1, I2, I3 {
public void foo() { .... }
}
私の現在の印象は次のとおりです。「一般」の場合、私は意味だけでなく、私は全体の継承チェーンの中を歩くと、この方法の「最初の宣言」が、また、次のような病的な例を見つけることができますこの単純なケースでそれらの病理学的な事例を無視して、そのようなオブジェクトが存在すれば作成が成功したので、コンパイルは成功したので、これらのメソッドはすべて同じシグネチャを持ち、Javaでは指定できませんどのようにオブジェクトが(I1、I2またはI3のように)表示されるかに依存して、これらのメソッドの実装が異なると、結果は常に同じになります。
ご協力いただければ幸いです。
コンパイル時ではなく実行時に実行することを除いて、おそらくJavaメソッド解決規則をエミュレートしてください。基本的には、継承ツリー(ルートに最も近いメソッド)の最初のメソッドを調べ、複数のメソッドがある場合は、スーパークラスから来るものを選択する必要があります。それらがすべてインターフェイスから来た場合は、任意に選択できます。 – biziclop
関連する質問は、これがデフォルトのメソッドでどのように動作するかです。 – biziclop
私のポストからは明らかではないかもしれませんが、これは私が現在実装しているものです。これが解決策であるかどうかはわかりません。多分もっと良い方法があるかもしれません。それが私が尋ねた理由です。ダイナミックな型定義はタイプ控除を使った静的型付けを目指していますが、このような大きな穴を残すことは私が明確な良心をもってできることではありませんので、このままでそのまま残すことができます。 –