Java 带子类的条件编译
Java conditional compilation with subclasses
如果有人在其他地方问过这个问题,但我找不到,我深表歉意。
基本上,我想知道带有条件编译的 Java class 是否有效(目的是删除 class 文件中一段代码的所有痕迹)在其子classes.
例如,让我们class A 及其子class 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.");
}
}
很明显什么都不会打印出来。但是,他们的 class 文件会包含编译后的 if 条件吗?
非常感谢!
Java不支持c、c++等宏
您可以使用标志在运行时启用或禁用断言,但不能使用宏
刚刚在 IntelliJ 中编译了 class,然后反编译了 .class
文件以查看它是否包含语句。没有。
我怀疑这取决于编译器(即 Java 语言规范没有说明是否必须包含这些内容,因此可以自由选择),并且您可能会找到一个编译器但是 会 包含这些语句。我用的是 Corretto Java 11.
不,不会。
您应该尝试创建您的 .class 文件,然后使用反编译器对其进行反编译,或者直接转到 javadecompilers.com 并上传您的 class 文件以确认您的答案。
如果根据您的代码制作源代码
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
}
如果为 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
}
以便在 javac 级别上进行此类优化,但为了保证,最好在编译之前删除源代码级别的代码部分,例如使用 preprocessor
如果有人在其他地方问过这个问题,但我找不到,我深表歉意。
基本上,我想知道带有条件编译的 Java class 是否有效(目的是删除 class 文件中一段代码的所有痕迹)在其子classes.
例如,让我们class A 及其子class 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.");
}
}
很明显什么都不会打印出来。但是,他们的 class 文件会包含编译后的 if 条件吗?
非常感谢!
Java不支持c、c++等宏 您可以使用标志在运行时启用或禁用断言,但不能使用宏
刚刚在 IntelliJ 中编译了 class,然后反编译了 .class
文件以查看它是否包含语句。没有。
我怀疑这取决于编译器(即 Java 语言规范没有说明是否必须包含这些内容,因此可以自由选择),并且您可能会找到一个编译器但是 会 包含这些语句。我用的是 Corretto Java 11.
不,不会。
您应该尝试创建您的 .class 文件,然后使用反编译器对其进行反编译,或者直接转到 javadecompilers.com 并上传您的 class 文件以确认您的答案。
如果根据您的代码制作源代码
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
}
如果为 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
}
以便在 javac 级别上进行此类优化,但为了保证,最好在编译之前删除源代码级别的代码部分,例如使用 preprocessor