合并射击3
15.35MB · 2025-12-03
你在代码中写下:
long a = 999999999; // 正常编译运行
为什么可行?因为:
999999999 位于 int 的取值范围内(-2147483648 ~ 2147483647);int 赋给 long 属于宽化转换(从较小范围到较大范围),是安全且无需强转的。对比:如果字面量超出 int 范围,就必须显式标记为 long:
long x = 2147483647; // OK(仍在 int 范围内)
long y = 2147483648; // 编译错误(默认按 int 解析,已溢出)
long z = 2147483648L; // OK(L 表示 long 字面量)
long w = 3000000000; // 编译错误
long v = 3000000000L; // OK
byte → short → int → long → float → doublechar → int → long → float → doubleArrayList → List → Collection → Object。注意:虽然“整数 → 浮点”也被视为宽化(比如 int → float、long → double),但它可能带来精度表示差异(浮点无法精确表示所有大整数)。
int:1、0xFF、0b1010、07 等。double:1.0、3.14、1e3 等。long:在整数字面量后加 L(推荐大写 L,避免和数字 1 混淆)。float:在浮点字面量后加 F。'a' 的类型是 char。在算术运算中,较小整数类型(byte、short、char)会先被提升为 int,再参与计算,结果至少是 int:
byte p = 1, q = 2;
var r = p + q; // r 的类型是 int
// byte s = p + q; // 编译错误:需要强制转换
byte s = (byte) (p + q); // 显式强转后 OK
byte a1 = 1 + 2; // OK:编译期常量折叠,且结果在 byte 范围内
byte a2 = 1 + p; // 编译错误:含变量参与,结果提升为 int
混合运算遵循“向更宽类型靠拢”的规则:int → long → float → double。例如:
double d = 1L + 1.0F; // 结果是 double
它们是两套不同机制:
int ↔ Integer、long ↔ Long 等)。可能创建对象,拆箱时还可能触发 NullPointerException。在方法重载选择上,优先级通常为:原始类型宽化 > 自动装箱/拆箱 > 可变参数。并且,编译器不会做“装箱再宽化”的组合步(例如不存在 int → Integer → Long 的路径)。
示例:
void f(long x) {}
void f(Integer x) {}
void f(int... xs) {}
f(1); // 调用 f(long) —— 原始类型宽化优先
void g(Long x) {}
// g(1); // 编译错误:不能从 int 直接变为 Long(不会先装箱为 Integer 再“宽化”为 Long)
超出 int 范围的整数字面量必须加 L,否则以 int 解析会编译失败。
整数除法会截断小数:1/2 == 0。若要小数结果,用 1.0、1d 或 1F 触发浮点运算:
double r1 = 1 / 2; // 0.0
double r2 = 1.0 / 2; // 0.5
整数 → 浮点虽属“宽化”,但可能有精度差异(尤其是 long → float、long → double)。对精度敏感的数量(如金额)请使用 BigDecimal。
拆箱可能 NPE:Integer n = null; int x = n; // NPE。
下列哪行会编译失败?为什么?
long a = 2147483647;
long b = 2147483648;
long c = 2147483648L;
下面的调用会选哪个重载?
void h(long x) {}
void h(Integer x) {}
h(1);
下面的结果分别是什么?
double x = 1 / 2;
double y = 1.0 / 2;
说明下面为何编译错误,如何修正?
byte b = 1;
byte c = 2;
byte d = b + c;
答案:
long b = 2147483648; 失败。2147483648 默认按 int 解析且超范围;写成 2147483648L 即可。h(long),因原始类型宽化优先于装箱。x == 0.0(整数除法先算出 0 再宽化),y == 0.5。b + c 提升为 int,赋给 byte 需强转:byte d = (byte) (b + c);。int,浮点字面量默认 double;超出范围要用后缀(L/F)。int。