gpt4 book ai didi

java - Java 中的解释性语言以及对 Java 方法的调用

转载 作者:行者123 更新时间:2023-12-02 08:20:34 33 4
gpt4 key购买 nike

我已经在 J​​ava 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代​​码:

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() 只是检查名称是否正确以及将调用哪个方法的参数是否或多或少与正式参数列表匹配。它的实现留给读者作为一个简单的练习。有意见吗?

关于java - Java 中的解释性语言以及对 Java 方法的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36305853/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com