javac相当于"-D"?

sho*_*osh 7 c++ java

有没有办法给java编译器一些可以运行的java代码访问的变量?
在C/C++中,我可以给出编译-DKEY=VALUE,这将导致预处理器#define的KEY等于VALUE.然后,我可以在编译时检查此值以影响正在编译的代码.
我找到了java-D,但是将值赋予java命令行System.getProperty().我想在编译时给出一个参数,而不是调用时间.

wer*_*ero 11

javac

-Akey[=value]
Run Code Online (Sandbox Code Playgroud)

命令行选项将信息传递给注释处理器.

  • 你能举例说明如何使用它吗? (2认同)

mar*_*inj 8

使用java注释,可以动态生成其他代码,可以在命令行上配置.它允许生成更多源代码,配置文件,xml文件,...主要限制是你只允许(重新)生成新的源文件,你不能修改现有的源文件.

下面是一个简短的教程,介绍如何允许javac命令指定在Java代码中可见的参数.这有用吗?IE浏览器.你可以指定一个布尔选项来禁用代码的某些部分,我很确定这些代码部分可以使用proguard之类的工具删除 - 甚至可以通过javac进行优化.其他用途是指定新版本号.这些用例主要是使用c ++ marcros.

所以,你需要:

  • 一个虚拟注释类,它将允许处理器运行.它应该只在您的应用程序中指定一次.
  • 一个处理器类,它将运行上面的虚拟注释,并生成选项类.它还将从javac命令行中读取选项.
  • 用于测试目的的虚拟主类.

在编译Main类之前,您还必须编译处理器文件.这当然仅在修改处理器类时完成.所有这三个文件都在底部.现在编译看起来如下(我在Windows上):

编译处理器:

javac .\com\example\ConfigWritterAnnotationProcessor.java
Run Code Online (Sandbox Code Playgroud)

然后Main.java带有处理器的附加参数:

javac -processor com.example.ConfigWritterAnnotationProcessor -AtextToPrint="Hello World!" -AenablePrint=true ./com/example/Main.java
Run Code Online (Sandbox Code Playgroud)

这就是全部,现在您可以运行Main.class,它将使用在编译期间使用上述参数设置生成的Options类.它看起来如下:

package com.example;
public class Options {
    public static final String textToPrint = "Hello World!";
    public static final boolean enablePrint = true;
}
Run Code Online (Sandbox Code Playgroud)

ProcessorStarterAnnotation.java

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
public @interface ProcessorStarterAnnotation {
}
Run Code Online (Sandbox Code Playgroud)

Main.java

package com.example;

@ProcessorStarterAnnotation
public class Main {
    public static void main(String[] args) {
      if ( com.example.Options.enablePrint ) {
        System.out.println(com.example.Options.textToPrint);
      }
      else {
        System.out.println("Print disabled");
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

ConfigWritterAnnotationProcessor.java

package com.example;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Map;
import java.util.Set;

@SupportedAnnotationTypes("com.example.ProcessorStarterAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedOptions({"textToPrint", "enablePrint"})
public class ConfigWritterAnnotationProcessor extends AbstractProcessor {
  private Map<String,String> options;

  @Override
  public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    options = processingEnv.getOptions();
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations,
                         RoundEnvironment currentRound) {

    if (!currentRound.processingOver()) {
      // This for-s are because processor is also run on newly created Options class.
      for (TypeElement te : annotations) {
        for (Element e : currentRound.getElementsAnnotatedWith(te)) {
          try {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating com.example.Options");
            JavaFileObject javaFile = processingEnv.getFiler().createSourceFile("com.example.Options");
            Writer w = javaFile.openWriter();
            try {
              PrintWriter pw = new PrintWriter(w);
              pw.println("package com.example;");
              pw.println("public class Options {");
              pw.println("    public static final String textToPrint = \"" + options.get("textToPrint") + "\";");
              pw.println("    public static final boolean enablePrint = " + options.get("enablePrint") + ";");
              pw.println("}");
              pw.flush();
            } finally {
              w.close();
            }
          } catch (IOException x) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                x.toString());
          }
        }
      }
    }
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)