编译没有依赖项的Java代码

时间:2014-07-14 00:48:22

标签: java compilation

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

public class Main {
    public static void main(String[] args) {
        // ...
        UnknownClass.unknownMethod();
    }
}

我希望它使用方法UnknownClass自动生成类unknownMethod()

public class UnknownClass {
    public static void unknownMethod() {}
}

但不能将其输出到输出.jar

1 个答案:

答案 0 :(得分:5)

  

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

没有。源代码的静态依赖项必须在编译时都可用。

  

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

AFAIK,No。

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

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


  

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

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

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


以下是一个例子:

   UnknownClass c = ...
   c.method(42);
   c.method(42.0);

有多个不同的解决方案:

   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) {...}
   }

等等。

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

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