Pac*_*ier 5 java compiler-construction constants literals
当我们声明一个时static final,Java编译器(或预编译器?)似乎足够聪明,可以检测到超出范围的数字:
public class Test {
// setup variables:
public static final int i_max_byte = 127;
public static final int i_max_byte_add1 = 128;
public static final int i_max_short = 32767;
public static final int i_max_short_add1 = 32768;
public static final int i_max_char = 65535;
public static final int i_max_char_add1 = 65536;
public static final char c_max_byte = 127;
public static final char c_max_byte_add1 = 128;
public static final char c_max_short = 32767;
public static final char c_max_short_add1 = 32768;
public static final short s_min_char = 0;
public static final short s_min_char_sub1 = -1;
public static final short s_max_byte = 127;
public static final short s_max_byte_add1 = 128;
// all these are OK:
public static final byte b1 = i_max_byte;
public static final byte b2 = s_max_byte;
public static final byte b3 = c_max_byte;
public static final byte b4 = (short) i_max_byte;
public static final byte b5 = (char) i_max_byte;
public static final char c1 = i_max_char;
public static final char c2 = s_min_char;
public static final short s1 = i_max_short;
public static final short s2 = c_max_short;
// pre-compiler complains "type-mismatch":
public static final byte _b1 = i_max_byte_add1;
public static final byte _b2 = s_max_byte_add1;
public static final byte _b3 = c_max_byte_add1;
public static final byte _b4 = (short) i_max_byte_add1;
public static final byte _b5 = (char) i_max_byte_add1;
public static final char _c1 = i_max_char_add1;
public static final char _c2 = s_min_char_min_us1;
public static final short _s1 = i_max_short_add1;
public static final short _s2 = c_max_short_add1;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码证明了for int,short和char值,只有当值超出指定变量类型的范围时,编译器才会抱怨.
但是对于long值,即使数字在范围内,编译器也会抱怨:
public class Test2 {
public static final long l_max_byte = 127;
public static final long l_max_byte_add1 = 128;
public static final long l_max_char = 32767;
public static final long l_max_char_add1 = 32768;
public static final long l_max_short = 65535;
public static final long l_max_short_add1 = 65536;
public static final long l_max_int = 2147483647;
public static final long l_max_int_add1 = 2147483648L;
// "type-mismatch" for all:
public static final byte b1 = l_max_byte;
public static final byte b2 = l_max_byte_add1;
public static final char c1 = l_max_char;
public static final char c2 = l_max_char_add1;
public static final short s1 = l_max_short;
public static final short s2 = l_max_short_add1;
public static final int i1 = l_max_int;
public static final int i2 = l_max_int_add1;
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器只在范围检测智能的 int,short和char值?
为什么编译器不对long值进行范围检测?
答案可能并不令人满意,但是……
\nJava语言规范第 5.2 节说:
\n\n\n赋值上下文允许将表达式的值 (\xc2\xa715.26) 赋给变量;表达式的类型必须转换为变量的类型。
\n...
\n另外,如果表达式是 byte、short、char 或 int 类型的常量表达式 (\xc2\xa715.28):
\n\n
\n- 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用缩小基元转换。
\n
对于编译良好的情况,常量表达式始终为 、 或 类型short,char并且int该值可以用目标类型表示。对于long类型来说,根据规范根本不允许这样的转换。
答案可能并不令人满意,因为下一个明显的问题是:
\n\n\n他们为什么要这样写规范?
\n
JLS 的链接部分中也给出了这个示例,这可以部分回答这个问题:这种隐式转换很可能主要用于您想要编写如下声明的情况
\nbyte b = 42;\nRun Code Online (Sandbox Code Playgroud)\n因为否则,您必须将int值 42 转换为字节,如下所示
byte b = (byte)42;\nRun Code Online (Sandbox Code Playgroud)\n从这个意义上说,您想要byte从long值初始化 a 的情况并不常见。
| 归档时间: |
|
| 查看次数: |
91 次 |
| 最近记录: |