专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Java编译器哪个好

Java编译器哪个好

更新时间:2021-05-26 15:49:52 来源:动力节点 浏览708次

Java编译器哪个好?API就是非常不错的,Java编译器读取源文件并生成类文件。(将它们组装到JAR,WAR,EAR和其他软件包中是另一种工具的责任。)源文件和类文件不一定是驻留在磁盘,SSD或内存驱动器中的真实操作系统文件。毕竟,当涉及到运行时API时,Java通常对于抽象是很好的,现在就是这种情况。这些文件是一些“抽象”文件,您必须通过API提供访问这些文件,这些文件可以是磁盘文件,但同时几乎可以是任何其他文件。将源代码保存到磁盘上只是为了让编译器在同一进程中运行以将其读回并在类文件准备好后对其进行相同操作,通常会浪费资源。

Java编译器作为运行时可用的API,要求您提供一些简单的API(或您喜欢的SPI)来访问源代码并发送生成的字节码。如果我们在内存中有代码,则可以有以下代码:

public Class<?> compile(String sourceCode, String canonicalClassName)
			throws Exception {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		List<JavaSourceFromString> sources = new LinkedList<>();
		String className = calculateSimpleClassName(canonicalClassName);
		sources.add(new JavaSourceFromString(className, sourceCode));
 
		StringWriter sw = new StringWriter();
		MemoryJavaFileManager fm = new MemoryJavaFileManager(
				compiler.getStandardFileManager(null, null, null));
		JavaCompiler.CompilationTask task = compiler.getTask(sw, fm, null,
				null, null, sources);
 
		Boolean compilationWasSuccessful = task.call();
		if (compilationWasSuccessful) {
			ByteClassLoader byteClassLoader = new ByteClassLoader(new URL[0],
					classLoader, classesByteArraysMap(fm));
 
			Class<?> klass = byteClassLoader.loadClass(canonicalClassName);
			byteClassLoader.close();
			return klass;
		} else {
			compilerErrorOutput = sw.toString();
			return null;
		}
	}

编译器实例可通过ToolProvider并且要创建编译任务,我们必须调用getTask()。该代码通过字符串编写器将错误写入字符串。文件管理器(fm)是在同一程序包中实现的,它只是将文件作为字节数组存储在映射中,其中的键是“文件名”。这是类加载器稍后在加载类时将获取字节的位置。该代码未提供任何可诊断的侦听器(请参见RT中Java编译器的文档),编译器选项或注释处理器要处理的类。这些都是空值。最后一个参数是要编译的源代码列表。我们仅在此工具中编译一个类,但是由于编译器API是通用的并且需要可迭代的源,因此我们提供了一个列表。由于存在另一个抽象级别,因此此列表包含JavaSourceFromString。

要开始编译,必须“调用”创建的任务,如果编译成功,则从生成的一个或多个字节数组中加载类。请注意,如果在我们编译的顶级类中有嵌套类或内部类,则编译器将创建几个类。这就是为什么即使只编译一个源类,我们也必须维护类的整个映射,而不是单个字节数组。如果编译不成功,则错误输出将存储在一个字段中并可以查询。

该类的使用非常简单,您可以在单元测试中找到示例:

private String loadJavaSource(String name) throws IOException {
		InputStream is = this.getClass().getResourceAsStream(name);
		byte[] buf = new byte[3000];
		int len = is.read(buf);
		is.close();
		return new String(buf, 0, len, "utf-8");
	}
...
	@Test
	public void given_PerfectSourceCodeWithSubClasses_when_CallingCompiler_then_ProperClassIsReturned()
			throws Exception {
		final String source = loadJavaSource("Test3.java");
		Compiler compiler = new Compiler();
		Class<?> newClass = compiler.compile(source, "com.javax0.jscc.Test3");
		Object object = newClass.newInstance();
		Method f = newClass.getMethod("method");
		int i = (int) f.invoke(object, null);
		Assert.assertEquals(1, i);
	}

以上就是动力节点小编介绍的"Java编译器哪个好",希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为您服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>