簡體   English   中英

Java中的解釋語言和對Java方法的調用

[英]Interpreted language in Java and calls to Java methods

我已經用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 $ KeySet類具有“包”可見性這一事實。 這意味着當我調用它的“size()”方法時,我從類中調用我的代碼不可見的方法。 Java很容易避免這個問題 - 方法keySet()返回類型為Set的值,因此使用的方法size()在public和抽象類“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),無法指定這些方法的不同實現,那么結果將始終相同。

任何幫助將不勝感激。

好的,這是我的解決方案。 它不是很好,但嘿,無論有用:

    public static Method findMethod(Class<?> cls, String name, Class<?>[] fa) {
    System.out.println("Checking class " + cls + " for method " + name);
    // since it is called recursively, we want to stop some day, and when we are
    // passed null (so most getSuperclass was called on Object.class or something similar)
    if (cls == null) {
        return null;
    }
    Method m = null;
    if ((m = findMethod(cls.getSuperclass(), name, fa)) != null) {
        return m;
    }
    // ok, if we're here, then m is null. so check if cls is public. it must be public, because
    // otherwise we won't be able to call it - we are definitely in different package. if class
    // isn't public, then check interfaces.
    if (!Modifier.isPublic(cls.getModifiers())) {
        System.out.println("Class is not public, and superclasses do not contain method " + name);
        System.out.println("Checking all interfaces");
        for (Class<?> iface: cls.getInterfaces()) {
            if ((m = findMethod(iface, name, fa)) != null) {
                return m;
            }
        }
    }
    return findMethodInClass(cls, name, fa);
}
private static Method findMethodInClass(Class<?> cls, String name, Class<?>[] fa) {
    Method m = null;
    // scan all methods and move plausible candidates to the start of an array
    Method[] mm = cls.getMethods(); 
    int n = 0;
    for (int i = 0 ; i < mm.length ; ++i) {
        if (checkMethod(mm[i], name, fa)) {
            mm[n++] = mm[i];
        }
    }
    if (n > 1) {
        System.out.println("Caveat: we have to perform more specific test. n == " + n);
        System.out.println("class: " + cls + "\nname: " + name);
        for (int i = 0 ; i < n ; ++i) {
            System.out.println(mm[i]);
        }
    }
    if (n > 0) {
        m = mm[0];
    }
    return m;
}

在findMethodInClass中調用的方法checkMethod()只檢查名稱是否正確,以及調用哪個方法的參數或多或少與正式參數列表匹配。 它的實現留給讀者一個簡單的練習。 任何意見?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM