8

我一直在玩 rJava 包,但由于 rJava 似乎不知道 Java 泛型类型,所以我很难使用泛型类型参数创建 java 对象。如果我有一个像这样的java类:

public class A<T> {
    private B<T> b;
    public A(B<T> b) {
        this.b = b;
    }
}

我想.jnew()通过传递一个已经创建的 B 对象(带有实例化类型参数)从 R 会话创建一个 A 对象,但是 rJava 总是给出错误:

java.lang.NoSuchMethodError: <init>

有什么解决方法吗?

4

1 回答 1

2

这个问题有很多活动部分。挖掘各个部分的文档,我认为您需要在中断的行上执行此操作:

gesinstance = .jnew("edu/cmu/tetrad/search/Ges", .jcast(dataset, "edu/cmu/tetrad/data/DataSet"))

关键区别在于.jcast对第二个参数的调用。(我没有安装 R,所以我无法对此进行测试 - 如果它不起作用,我将根据您可以提供的有关新错误消息的任何反馈更新我的答案。)

那么问题是“为什么会这样?” 答案似乎是:

  1. 在 Java 方面,DataReader.parseTabularData返回一个具有DataSet您所指出的类型的对象,但DataSet它是一个接口而不是一个类。这必然意味着返回的实际对象属于实现该DataSet接口的某个类。
  2. 由于我不清楚的原因,rJava 包并不能很好地处理多态性。它要求您调用与您传递的对象具有“精确”签名匹配的方法。在这种情况下,您需要从获得的任何特定类“向上转换”到 interface DataSet。请参阅.jnew( https://www.rforge.net/doc/packages/rJava/html/jnew.html ) 的文档,尤其是它们用“...”表示的参数。这指的是您参考文档的相应部分.jcallhttps://www.rforge.net/doc/packages/rJava/html/jcall.html),然后解释调用的要求.jcasthttps://www.rforge .net/doc/packages/rJava/html/jcast.html)和一些例子。

您得到的错误java.lang.NoSuchMethodError: <init>是告诉您 JVM 找不到您调用的构造函数。在您在评论中发布的示例中,这看起来很神秘。(顺便说一句,编辑您的问题可能会很好,并将该信息包含在此处以供后代使用。)代码看起来确实正确,而且,了解 Java,我直观地期望接口尊重 Java 的多态性。鉴于此(无论出于何种原因),R 的接口在不考虑继承的情况下进行“精确”类型匹配,很明显,由于上面的原因 #1,它不会找到构造函数。

最后,在我对 Tetrad 的有限探索中,我实际上并没有遇到任何使用泛型的 Java 类。事实证明,这是一个完全的红鲱鱼。如果将来出现问题,您可能需要查看“类型擦除”(https://docs.oracle.com/javase/tutorial/java/generics/erasure.html)。如果您在 Java 和 C、C++、Fortran 以及任何 Java 认为“本机”的语言之间进行交互,那么您将通过处理类型擦除形式来处理本机代码中的泛型。不过,rJava 接口可能会有所不同,因为这似乎属于使您在当前问题上绊倒的相同结构类型。(也许以后值得它自己的赏金!)

于 2015-09-17T01:06:29.480 回答