栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java JavaCompiler.run()也可以编译匿名类

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java JavaCompiler.run()也可以编译匿名类

显然,您

loadStrategyClass
是在custom中定义的
ClassLoader
。问题在于,
defineClass
对于感兴趣的类仅调用一次是不够的,您的类加载器通常必须通过实现才能按需解析类
findClass
,以便JVM可以解析依赖项,例如内部类。

您没有指定如何获取方法的

strategyClassFile
参数
loadStrategyClass
。由于您没有任何选择地运行编译器,因此我想您只是相对于源文件查找了文件。要解决其他依赖关系,需要知道类目录的实际根目录。当您定义存储类文件的位置时,它将变得更加容易,例如

// customize these, if you want, null triggers default behaviorDiagnosticListener<JavaFileObject> diagnosticListener = null;Locale locale = null;JavaCompiler c = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager fm    = c.getStandardFileManager(diagnosticListener, locale, Charset.defaultCharset());// define where to store compiled class files - use a temporary directoryPath binaryDirectory = Files.createTempDirectory("compile-test");fm.setLocation(StandardLocation.CLASS_OUTPUT,    Collections.singleton(binaryDirectory.toFile()));JavaCompiler.CompilationTask task = c.getTask(null, fm,    diagnosticListener, Collections.emptySet(), Collections.emptySet(),    // to make this a stand-alone example, I use embedded source pre    Collections.singleton(new SimpleJavaFileObject(        URI.create("string:///Class1.java"), Kind.SOURCE) { public CharSequence getCharContent(boolean ignoreEncodingErrors) {     return "package test;npublic class Class1 { public class Inner {} }"; }        }));if(task.call()) try {    URLClassLoader cl = new URLClassLoader(new URL[]{ binaryDirectory.toUri().toURL() });    Class<?> loadedClass = cl.loadClass("test.Class1");    System.out.println("loaded "+loadedClass);    System.out.println("inner classes: "+Arrays.toString(loadedClass.getClasses()));} catch(ClassNotFoundException ex) {    ex.printStackTrace();}

在上面的示例中,我们知道了类目录的根,因为已经定义了它。这允许简单地使用现有的

URLClassLoader
而不是实现新型的类加载器。当然,使用自定义文件管理器,我们还可以将内存存储用于临时目录。


您可以使用此API来发现生成的内容,这使您可以使用生成的类而无需事先知道要编译的源文件中存在哪些包或内部类声明。

public static Class<?> compile(    DiagnosticListener<JavaFileObject> diagnosticListener,    Locale locale, String sourceFile) throws IOException, ClassNotFoundException {    JavaCompiler c = ToolProvider.getSystemJavaCompiler();    StandardJavaFileManager fm        = c.getStandardFileManager(diagnosticListener, locale, Charset.defaultCharset());    // define where to store compiled class files - use a temporary directory    Path binaryDirectory = Files.createTempDirectory("compile-test");    fm.setLocation(StandardLocation.CLASS_OUTPUT,        Collections.singleton(binaryDirectory.toFile()));    JavaCompiler.CompilationTask task = c.getTask(null, fm,        diagnosticListener, Collections.emptySet(), Collections.emptySet(),        fm.getJavaFileObjects(new File(sourceFile)));    if(task.call()) {        Class<?> clazz = null;        URLClassLoader cl = new URLClassLoader(new URL[]{binaryDirectory.toUri().toURL()});        for(JavaFileObject o: fm.list( StandardLocation.CLASS_OUTPUT, "", Collections.singleton(Kind.CLASS), true)) { String s = binaryDirectory.toUri().relativize(o.toUri()).toString(); s = s.substring(0, s.length()-6).replace('/', '.'); clazz = cl.loadClass(s); while(clazz.getDeclaringClass() != null) clazz = clazz.getDeclaringClass(); if(Modifier.isPublic(clazz.getModifiers())) break;        }        if(clazz != null) return clazz;        throw new ClassNotFoundException(null, new NoSuchElementException("no top level class generated"));    }    throw new ClassNotFoundException(null,        new NoSuchElementException("compilation failed"));}

如果使用此方法动态绑定插件或模块,则可以扩展搜索以查找实现特定接口或具有特定批注的结果类。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/514511.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号