是否有一种方法可以在java中定义标志,并仅在这些标志已定义时运行代码?
在是否有一种方法可以在java中定义标志,并仅在这些标志已定义时运行代码?,java,Java,在c\c++中可以定义: #ifndef <token> /* code */ #else /* code to include if the token is defined */ #endif #ifndef /*代码*/ #否则 /*如果定义了令牌,则要包含的代码*/ #恩迪夫 我的问题是,有没有一种用java实现的方法?(未定义全局静态变量..) 例如,我只想在调试模式下运行一些代码 谢谢 上面粘贴的剪贴是为预处理器准备的,预处理器在编译之前“转换”源代码
c\c++
中可以定义:
#ifndef <token>
/* code */
#else
/* code to include if the token is defined */
#endif
#ifndef
/*代码*/
#否则
/*如果定义了令牌,则要包含的代码*/
#恩迪夫
我的问题是,有没有一种用java实现的方法?(未定义全局静态变量..)
例如,我只想在调试模式下运行一些代码
谢谢 上面粘贴的剪贴是为预处理器准备的,预处理器在编译之前“转换”源代码 Java没有等价的语言结构,因此答案是您不能这样做 编辑:但是您可以使用常规条件来实现您的目标,因为这样编译器将以所需的方式优化字节码(感谢@StephenC指出这一点) 但我个人更喜欢在需要的地方扩展API进行调试,这将隐藏实现细节,并且可以在运行时更改。当然,这是特定于场景的 例如,这类似于Log4j-s,它允许您检查代码是否处于调试模式
我建议使用这种模式,因为这不会破坏(太多:)我们钟爱的面向对象概念。答案是否定的。不是你的意思 在Java中执行此类操作的方式如下:
private static final boolean flag = true; /* or false :-) */
if (flag) {
/* code */
} else {
/* different code */
}
java没有预处理器(如C和C++)。但是,如果
flag
是编译时常量表达式,编译器将优化掉上述if
语句中未使用的分支。这是一种有限形式的条件编译。请注意,控制标志
常量可以从其他类导入
(IIRC,此行为在JLS中指定……这意味着您可以依靠任何符合标准的Java编译器来完成。)
@Treebranch评论说“这”会导致代码膨胀
#ifdef
条件编译也可以这样说。(宏和#include
可以用来减少源代码膨胀……但这是以可读性、可维护性等为代价的,这也是Java设计人员拒绝支持任何源代码预处理的原因。)Java中没有什么比条件编译更好的了。(正如xea所说) 根据你想解决的问题,有很多类似的方法 一种是使用静态final变量设置为编译时常量(正如Stephen所写)。编译器实际上不会包含不可能路径的字节码。但它仍然必须是合法的java,这意味着您不能在一个这样的块中声明变量并在另一个块中使用它
我知道到目前为止我所看到的所有案例都可以使用OO构造来解决。例如,您可以通过调用抽象方法替换您的IF,并提供调试和生产实现。 < P> java作为一种语言,没有类似的预处理或宏,如C或C++,但是,有一些工具,可以处理这些事情。为了方便使用,您需要将它们连接到Maven或Ant构建中。我认为@StephenC提出的是一个不错的选择。或者,您可以尝试使用AspectJ编入您想要用于特定实现的代码。当您不希望将方面作为实现的一部分时,您可以简单地删除它(不要在代码中编织)。AspectJ根据您指定的位置类型(称为切入点)修改字节码(编译的Java代码)。这特别适合于将日志添加到程序中
如果这是一种您感兴趣的方法,请查看:和。建议使用最终静态布尔变量的方法与建议的功能最接近,因为编译器甚至对其进行了优化。如果该标志设置为false,则甚至不会生成块中包含的字节码 让我举一个例子:
public class Optimized {
private static final boolean DEBUG = true;
public static void main(String[] args) {
if(DEBUG){
System.out.println("DEBUG enabled");
}
}
}
这将生成字节码
public class Optimized {
public Optimized();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String DEBUG enabled
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
字节码如下所示
public class Optimized {
public Optimized();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
}
公共类优化{
公共优化();
代码:
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:返回
}
因此,好吧,这是最接近Java中的预编译指令。OP问“有没有一种方法可以在Java中实现它?(它没有定义全局静态变量…)”Java没有全局变量。。。从技术上说,Read是不成熟的。可以说,<代码>静态最终< /COD>字段等同于全局变量,例如C++(至少从使用角度来看)…但是你的解释是通过OP的接受来确认的,所以你也得到了我的+1:-p)@ Pyt Tort Rok。静态的最终字段不是全局的,因为在C、C++和FORTRAN中变量可以是全局的。它们必须用类名限定,即使这样,它们也不一定可见。除此之外,我的回答是“不-不是你的意思”。“你可以使用常规条件来实现你的目标,但这不会影响构建过程,这取决于你的令牌。”-严格来说不是真的。如果情况
public class Optimized {
public Optimized();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
}