带有子类的Java条件编译
如果有人在别的地方问过我,但我找不到,我道歉 基本上,我想知道一个带有条件编译的Java类(用于删除类文件中代码片段的所有痕迹)是否能在其子类上工作 例如,让我们按如下方式实现类A及其子类B:带有子类的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
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
并自己检查呢?