编译没有依赖项的Java代码

Vic*_*748 8 java compilation

我有一个java程序的源代码,但我没有它的依赖项.是否可以编译使用无法解析的字段,类和方法的Java代码?如果没有,是否有一个程序或Eclipse插件会自动生成在编译期间无法解析的假类,变量和方法?请举例说明.

public class Main {
    public static void main(String[] args) {
        // ...
        UnknownClass.unknownMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想让它UnknownClass用一个方法自动生成Class unknownMethod():

public class UnknownClass {
    public static void unknownMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

但不要在输出.jar中导出它

Ste*_*n C 5

是否可以编译使用无法解析的字段,类和方法的Java代码?

不可以.源代码的静态依赖项必须在编译时都可用.

如果没有,是否有一个程序或Eclipse插件会自动生成在编译期间无法解析的假类,变量和方法?

AFAIK,不.

事实上,我认为在技术上建立这样一个程序是不可能的.这将需要推断我们没有任何信息的类和方法的签名.我认为不可能准确地做到这一点; 即准确到足以使签名与真实类的实际签名相匹配.

(需要解决的一些问题是推断类的正确超类型,推断参数的正确类型和方法的结果,推断方法是否具有变量,推断方法是否存在重载等等.这些问题很容易处理,有些肯定不是.)


但Bukkit是如何使用CraftBukkit.jar和Bukkit.jar做到的?在Bukkit.jar中,有没有内部代码的方法头,但是在编译BUkkit.jar的代码时,它适用于Craftbukkit.jar.

我想你已回答了自己的问题.类层次结构和方法标头位于提供的Bukkit JAR文件中.因此,不需要推断它们.

相比之下,您要求在这里做的是从干净的平板推断类层次结构和方法签名...以及使用它们的代码(您的源代码)隐含的一些约束.


这是一个例子:

   UnknownClass c = ...
   c.method(42);
   c.method(42.0);
Run Code Online (Sandbox Code Playgroud)

有多种不同的解决方案:

   public class UnknownClass ... {
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       int method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(int arg) {...}
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(byte arg) {...}
       void method(double arg) {...}
   }

   public class UnknownClass ... {
       void method(double... arg) {...}
   }
Run Code Online (Sandbox Code Playgroud)

等等.

问题:哪个是正确的; 即与真实中的实际签名相匹配的那个UnknownClass

答:我们无从得知!它很重要,因为如果我们弄错了,当您尝试针对包含真实类的JAR运行编译代码时,可能会出现类加载器错误.