所以在C ++中有一个预处理器用值替换预处理器指令。现在我的问题是:JAVA是否有像Java中的预处理器? 现在。我们知道在Java中,switch语句的case值必须是在编译时评估的东西。例如:
int month = 5;
switch(month) {
case 1: doSth() break;
...
case month: doSth() break;
现在在这个例子中,我不能使用" case month:"因为变量month的值在运行时得到评估。但是如果我像这样添加final关键字:
final month = 5;
之后如果我做同样的事情,但使用具有final关键字的变量,一切都会起作用。 现在你能解释一下这是什么,这是预处理的#34;代码可供我查看?
答案 0 :(得分:0)
所以在字节码编译后,内存中没有变量“月”,而“月”的位置是“5”?
是和否。发生的事情是final
关键字告诉编译器变量不能改变,因此它可以被视为常量并用于需要常量的地方。如何在封面下发生这种情况并不重要,但在实践中,常数值将被取代。
现在让我们考虑你的代码:
int month = 5;
switch(month) {
case 1: doSth() break;
...
case month: doSth() break; // compilation error
这里有些东西不对,因为你的开关变量与你的一个案例相同。唯一可能的路径是month
情况,因此所有其他情况都是死代码。也许你的意思是:
int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Still a compilation error
这看起来好一点但不会编译,因为monthOfInterest
不是“常量表达式”。在这里,我们来看你原来的问题。大小写选择器必须是数字文字或可在编译时计算的表达式。所以我们将其更改为:
final int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // This is valid code
此“行为”好像monthOfInterest
被常量5
取代。请注意,这与:
final int monthOfInterest;
...
monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops, compilation error again
声明变量final
并稍后对其进行初始化是完全合法的。编译器将确保您只设置一次值,但在这种情况下monthOfInterest
不再是常量表达式,并且此代码将无法编译。
最后一点说明。考虑:
final int monthOfInterest = 1;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops again, different compilation problem
由于现在您有两个具有相同值的情况,因此无法编译。