带有子类的Java条件编译

带有子类的Java条件编译,java,conditional-compilation,Java,Conditional Compilation,如果有人在别的地方问过我,但我找不到,我道歉 基本上,我想知道一个带有条件编译的Java类(用于删除类文件中代码片段的所有痕迹)是否能在其子类上工作 例如,让我们按如下方式实现类A及其子类B: public class A { protected static final boolean ASSERTS = false; protected A() { if (ASSERTS) { System.out.println("A: ASSER

如果有人在别的地方问过我,但我找不到,我道歉

基本上,我想知道一个带有条件编译的Java类(用于删除类文件中代码片段的所有痕迹)是否能在其子类上工作

例如,让我们按如下方式实现类A及其子类B:

public class A {
    protected static final boolean ASSERTS = false;

    protected A() {
        if (ASSERTS) {
            System.out.println("A: ASSERTS enabled.");
        }
}

public class B extends A {
    protected B() {
        if (ASSERTS) {
            System.out.println("B: ASSERTS enabled.");
        }
}
很明显,不会打印出任何内容。但是,它们的类文件会包含编译的if条件吗


非常感谢

java不支持像C++这样的宏
您可以在运行时使用标志来启用或禁用断言,但没有宏只需在IntelliJ中编译类,然后反编译
.class
文件以查看它是否包含语句。事实并非如此

我怀疑这取决于编译器(即Java语言规范没有说明是否必须包含这些内容,因此它们可以自由选择),并且您可能会找到包含这些语句的编译器。我使用的是Corretto Java 11。

不,不会


您应该尝试创建您的.class文件,然后使用反编译器对其进行反编译,或者直接转到javadecompilers.com上传您的类文件以确认您的答案。

如果根据您的代码生成源代码

public class A {
protected static final boolean ASSERTS = false;

protected A() {
    if (ASSERTS) {
        System.out.println("A: ASSERTS enabled.");
    }
}

public static class B extends A {
  protected B() {
      if (ASSERTS) {
          System.out.println("B: ASSERTS enabled.");
        }
      }
    }
}
用javac编译,然后用FALSE得到字节码

  public class A {
    protected static final boolean ASSERTS;
    protected A();
    Code:
       0: aload_0
       1: invokespecial #2                  // Method java/lang/Object."<init>":()V
       4: return
  }
公共A类{
受保护的静态最终布尔断言;
保护A();
代码:
0:aload_0
1:invokespecial#2//方法java/lang/Object。“:()V
4:返回
}
如果为TRUE,我们将得到下面的编译字节码

public class A {
  protected static final boolean ASSERTS;

  protected A();
    Code:
       0: aload_0
       1: invokespecial #2                  // Method java/lang/Object."<init>":()V
       4: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       7: ldc           #4                  // String A: ASSERTS enabled.
       9: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      12: return
}
公共A类{
受保护的静态最终布尔断言;
保护A();
代码:
0:aload_0
1:invokespecial#2//方法java/lang/Object。“:()V
4:getstatic#3//Field java/lang/System.out:Ljava/io/PrintStream;
7:ldc#4//字符串A:已启用断言。
9:invokevirtual#5//方法java/io/PrintStream.println:(Ljava/lang/String;)V
12:返回
}

因此,在javac级别上,这种优化是有效的,但为了保证,最好在编译之前删除源代码级别上的代码部分,例如使用

为什么不运行Java反汇编程序
javap
并自己检查呢?