Java JVM语言互操作性

Java JVM语言互操作性,java,scala,compiler-construction,programming-languages,java-bytecode-asm,Java,Scala,Compiler Construction,Programming Languages,Java Bytecode Asm,最近我正在为一种JVM编程语言编写一个编译器,我意识到了一个问题 我想从我的编程语言访问Java方法,并允许Java方法访问我的语言中的方法。问题是我需要知道Java方法签名,才能在生成的字节码中调用它,反之亦然 我一直在想Scala是如何做到这一点的。这是我的想法 Scala访问类路径上的.java文件并解析它们,从中提取方法签名 .java文件被编译为.class文件。然后使用Java ASM库访问.class文件并获取方法签名。此方法的问题是必须首先编译.java文件 .java使用反射动

最近我正在为一种JVM编程语言编写一个编译器,我意识到了一个问题

我想从我的编程语言访问Java方法,并允许Java方法访问我的语言中的方法。问题是我需要知道Java方法签名,才能在生成的字节码中调用它,反之亦然

我一直在想Scala是如何做到这一点的。这是我的想法

  • Scala访问类路径上的
    .java
    文件并解析它们,从中提取方法签名
  • .java
    文件被编译为
    .class
    文件。然后使用Java ASM库访问
    .class
    文件并获取方法签名。此方法的问题是必须首先编译
    .java
    文件
  • .java
    使用反射动态加载文件。问题是我认为JVM不允许加载编译器类路径之外的类 查看Scala,它与其他JVM语言配合得很好,但我找不到有关它具体如何工作的信息


    Scala如何获得其他JVM语言方法的方法签名

    我认为您混淆了类路径和源路径:类路径上没有
    .java
    .scala
    文件,有
    .class
    文件(可能在
    .jar
    内)。因此,对于依赖项(在类路径上),您不需要做任何特殊的事情。它们可以对您的语言(包括项目的早期版本)有自己的依赖关系,但它们已经根据定义进行了编译

    现在,对于混合项目,在源路径上有Java和您的语言


    选项3的问题不是“JVM不允许加载编译器类路径之外的类”,而是反射也只对类有效,而不对源文件有效。

    您应该添加希望从您的语言和从java访问java方法的信息。(另一个答案被删除)混合使用java语言是一个相当高级的用例,它可能是高级的,但Scala/java等语言可以做到这一点。混合使用这两种语言并不少见,将来我将不得不实现这一功能。反射只提供java->yourLang互操作性,即:您可以从代码中调用java内容,但不能反过来调用。为了让它反过来工作,您必须生成
    javac
    可以使用的东西,即将您的东西编译成jvm字节码,并将
    .class
    交给
    javac
    。这很有意义!这意味着,如果一种新的JVM语言被开发出来,Scala将不得不编写新的解析器来获取信息?这难道不意味着Java有Scala的解析器来获取Scala方法签名吗?Java不需要了解Scala,Scala可以为自己的类生成存根,所以简单的类只包含用于编译Java的方法签名。因此,如果还不能编译scala类、普通类或存根,javac将看到编译后的scala类。@Michael javac不允许编译混合项目。Scalac也不允许编译包含Java或Scala以外其他语言的项目。如果我重复你说的话。Scala将使用存根方法生成
    .class
    文件。然后在Java编译了它的类之后,它会运行Scala编译器并完全生成方法?@Michael Yep,看看C/Cpp的编译是如何工作的,你有特殊的头文件,所以你不需要包含完整的代码,因为这可能并不总是可能/容易的。或者您需要在文件的顶部定义方法,但在较低的位置实现它——这样编译器就已经知道这个方法了。但在这里,您需要生成它们。然后再次编译为正常的完整类。