当前位置: 首页 > 知识库问答 >
问题:

让Javac来接我的班

孟英锐
2023-03-14

问题背景:
生成一个java文件,其中包含一个不存在的超类的类;让javac解析类,但不编译它;通过编程生成超级类(这意味着没有类文件);最后让javac成功地生成一个类文件。

这里是CompilerAPITest.java

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Logger;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;    
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
* A test class to test dynamic compilation API.
*
*/
public class CompilerAPITest {
    static final Logger logger = Logger.getLogger(CompilerAPITest.class.getName()) ;

    public void doCompilation (){
        File[] files = {new File("/home/guestu/GeneratedClass.java")};

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
        /* Prepare a list of compilation units (java source code file objects) to input to  compilation task*/
        Iterable<? extends JavaFileObject> compilationUnits = stdFileManager.getJavaFileObjects(files);

        /*Create a diagnostic controller, which holds the compilation problems*/
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
        /*Create a compilation task from compiler by passing in the required input objects prepared above*/
        CompilationTask compilerTask = compiler.getTask(null, stdFileManager, diagnostics, null, null, compilationUnits) ;

        boolean status = compilerTask.call();
        if (!status){//If compilation error occurs
            /*Iterate through each compilation problem and print it*/
            for (Diagnostic diagnostic : diagnostics.getDiagnostics()){
                System.out.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
            } 
    }
    try {
       stdFileManager.close() ;//Close the file manager
    } catch (IOException e) {
 }

//Here is Helloworld.java
public class Helloworld extends GeneratedClass{
    public static void main(String[] args){
        System.out.println("Hello");

    }

}

//And here is GeneratedClass.java
package com.sun.tools.javac.parser;

import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;

/* This class programmatically produces the superclass "GeneratedClass" with signature public class GeneratedClass{} */

public class GeneratedClass {
    TreeMaker maker;
    Names names;
    public GeneratedClass(ParserFactory fac) {
        maker = fac. F;
        names = fac.names;
    }

    public JCCompilationUnit getTree() {
        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
        defs.append(makeClassDecl());
        return maker.TopLevel(List.<JCAnnotation>nil(), null, defs.toList());
    }

    /* This is a class decalaration node for public class GeneratedClass{}*/
    protected JCClassDecl makeClassDecl() {
        JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
        Name name = names.fromString("GeneratedClass");
        return maker.ClassDef(mods, name, List.<JCTypeParameter>nil(), null, List.<JCExpression>nil(), List.<JCTree>nil());
    }
}

我目前的挑战

我已经通过编程生成了一个类文件(GeneratedClass)。我希望java编译器能够使用它来编译Helloworld。JAVA我尝试过上述方法,但Helloworld无法编译,因为它无法获取GeneratedClass。有没有办法做到这一点?谢谢你抽出时间。

共有1个答案

鞠通
2023-03-14

我想你必须自定义文件管理器。但是您的任务似乎非常适合注释处理器。代码将被解析,如果一些类丢失了,这是完全可以的。解析后的代码get的模型被传递给注释处理器,注释处理器可以做任何选择。甚至还有一些用于编写生成类的架构体系。看到没

http://docs.oracle.com/javase/7/docs/api/javax/annotation/processing/Processor.html

http://deors.wordpress.com/2011/10/08/annotation-processors/

 类似资料:
  • 我已经调试这段代码好几个小时了,试图让输出正确无误。它在早期工作,但输出中存在逻辑错误,因此我进入并在输出函数中添加了循环和一个额外参数。 现在g给我以下错误: Student.cpp:在成员函数“void Student::input data(std::string,int,STD::string 如何修复此代码?:

  • 问题内容: 我如何知道用来构建jar的Java编译器的版本?我有一个jar文件,它可以在三个JDK中的任何一个中构建。我们需要确切地知道哪一个,以便我们证明兼容性。编译器版本是否嵌入在类文件或jar中的某个位置? 问题答案: 您不一定无法从JAR文件本身中分辨出来。 下载十六进制编辑器,然后在JAR中打开一个类文件,并查看字节偏移量4到7。内置了版本信息。 http://en.wikipedia.

  • 我创建了一些android应用程序,但只使用常规布局和视图。现在我正在学习一个游戏开发,我知道我需要使用自定义图形来绘制画布或打开gl来获得更好的图形和性能。我只是不知道从哪里开始。例如,要获得这样的图形(请参见附件),在画布上绘制就足够了,或者我应该学习OpenGL,还是只有使用unity或libgdx这样的工具才能实现?

  • 投递岗位:空间运营专员实习生(暑期实习) 今天上午下课休息期间,突然接到蔚来hr小姐姐的电话,看着号码来自广东深圳,上滑接通,还没反应过来,谁知道直接就开始面试了,真的非常措不及防😱😱😱而且简历都已经投了半个月了 接通后小姐姐问了两个问题: 1.请问你有过什么实习经历吗? 2.你能详细描述一下参加过的活动吗? 这时候,马上要上课了(为什么在课间休息打过来啊😥😥😥),于是我跟小姐姐说马上

  • 问题内容: 我一直在尝试制作一个Java项目。它使用Struts 2标签。无论何时要单击都有一个按钮,它应该更新数据库中的值。 但我收到此错误: 没有为操作com.comviva.im.ui.action.sysadmin.CUGAction和结果输入定义结果 问题答案: 没有为操作com.comviva.im.ui.action.sysadmin.CUGAction和结果输入定义结果 这意味着您

  • 我有一个xml结构: 我创建了一个AddRecordByInfoMatch()方法,只要存在匹配项,该方法就会尝试将新节点添加到任意给定ID中: 考虑到ID=333,我这样测试运行它: 不幸的是,输出;显示时,将新记录添加到ID为111的文章中以获得: 我希望它位于ID 333的文章节点内,这是我在函数调用中指定的。我在xpath表达式中做错了什么??或者我怎样才能做到这一点?任何帮助都将受到高度