Java 如果不在类文件中,编译后的代码将存储在其中
最近我在阅读时遇到一个问题 在第5页第2章 Java虚拟机要执行的编译代码是 使用独立于硬件和操作系统的二进制文件表示 格式,通常(但不一定)存储在文件中,称为 类文件格式 这个括号是原因,但不一定是原因 问题是, 在这种情况下,编译后的代码将不会存储在类文件中?如果它不会存储在类文件中,那么在哪里以及如何存储Java 如果不在类文件中,编译后的代码将存储在其中,java,compiler-construction,jvm,.class-file,java-compiler-api,Java,Compiler Construction,Jvm,.class File,Java Compiler Api,最近我在阅读时遇到一个问题 在第5页第2章 Java虚拟机要执行的编译代码是 使用独立于硬件和操作系统的二进制文件表示 格式,通常(但不一定)存储在文件中,称为 类文件格式 这个括号是原因,但不一定是原因 问题是, 在这种情况下,编译后的代码将不会存储在类文件中?如果它不会存储在类文件中,那么在哪里以及如何存储 编辑:请注意,问题不是关于类加载器。在java中,类加载器从何处编译二进制取决于它的实现。 可以编写一个类加载器,从数据库、网络、内存或任何其他可思考的位置加载它的类 默认的java使用
编辑:请注意,问题不是关于类加载器。在java中,类加载器从何处编译二进制取决于它的实现。 可以编写一个类加载器,从数据库、网络、内存或任何其他可思考的位置加载它的类
默认的java使用目录或JAR中的文件,因此这就是“通常”的来源,“不一定”只是暗示可能有其他实现。将编译后的代码存储在.class文件中只是获取JVM可执行代码的标准且更方便的方法,同样的编译代码可以从许多其他来源获得,它可以作为文本或二进制流从数据库、网络连接或运行时的内存中获得,或者是的,这个问题是关于类加载器的 类加载器是JVM引入类的(唯一)方式。这些类可以是文件、JAR存档、网络上的某个地方、数据库blob中、共享内存中、纸带上(如果您的机器有纸带读取器),甚至可以动态生成 这就是你问题的答案
标准编译器用于编写类文件,但正如Peter所评论的,这不一定是这样。最重要的是,javac命令编写类文件并不意味着我们必须使用这些文件。通常将它们打包到JAR中,然后使用它。您似乎对如何在内存中生成java类文件更感兴趣,因此:
public class CompileSourceInMemory {
public static void main(String args[]) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
out.println("public class HelloWorld {");
out.println(" public static void main(String args[]) {");
out.println(" System.out.println(\"This is in another java file\");");
out.println(" }");
out.println("}");
out.close();
JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
boolean success = task.call();
if (success) {
try {
Class.forName("HelloWorld").getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { null });
} catch (ClassNotFoundException e) {
System.err.println("Class not found: " + e);
} catch (NoSuchMethodException e) {
System.err.println("No such method: " + e);
} catch (IllegalAccessException e) {
System.err.println("Illegal access: " + e);
} catch (InvocationTargetException e) {
System.err.println("Invocation target: " + e);
}
}
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
公共类编译源内存{
公共静态void main(字符串args[])引发IOException{
JavaCompiler=ToolProvider.getSystemJavaCompiler();
DiagnosticCollector diagnostics=新建DiagnosticCollector();
StringWriter编写器=新的StringWriter();
PrintWriter out=新的PrintWriter(writer);
println(“公共类HelloWorld{”);
println(“publicstaticvoidmain(stringargs[]){”);
println(“System.out.println(\“这在另一个java文件中\”);”;
out.println(“}”);
out.println(“}”);
out.close();
JavaFileObject file=newJavaSourceFromString(“HelloWorld”,writer.toString());
IterableWell您可以将其保存在一个字节[]在内存中,或者在数据库中。@PeterLiljenberg,这将由编译器定义,对吗?java编译器只是一个java类,您可以调用它,所以是的,输出将由编译器实现决定。阅读官方文档中的更多内容:这是关于从编译代码加载类,如何生成编译代码?Tha这只是另一个特例。代码将在内存中生成/编译,然后由类加载器加载…这是关于获取生成的编译代码,生成编译代码如何?+1是关于从编译代码加载类,生成编译代码如何?检查链接,这也是