杰瑞科技汇

java int转换short

数据范围

  • int (整数): 32位,范围是 -2,147,483,6482,147,483,647 (约 ±21亿)。
  • short (短整型): 16位,范围是 -32,76832,767

short 的范围比 int 小得多,当将一个 int 值赋给 short 变量时,Java 编译器会进行检查int 的值超出了 short 的表示范围,编译器会报错,因为它知道这会导致数据丢失。

java int转换short-图1
(图片来源网络,侵删)

直接赋值(需要显式类型转换)

int 的值在 short 的范围内,可以直接赋值,但必须使用强制类型转换(cast),告诉编译器你明确知道自己在做什么,并愿意承担潜在的风险。

public class IntToShortExample {
    public static void main(String[] args) {
        int intValue1 = 100;
        short shortValue1;
        // 情况1:int的值在short的范围内,可以成功转换
        // 必须使用 (short) 进行强制转换
        shortValue1 = (short) intValue1;
        System.out.println("转换成功: " + intValue1 + " -> " + shortValue1);
        int intValue2 = 32767; // short的最大值
        short shortValue2 = (short) intValue2;
        System.out.println("转换成功: " + intValue2 + " -> " + shortValue2);
        int intValue3 = -32768; // short的最小值
        short shortValue3 = (short) intValue3;
        System.out.println("转换成功: " + intValue3 + " -> " + shortValue3);
    }
}

输出:

转换成功: 100 -> 100
转换成功: 32767 -> 32767
转换成功: -32768 -> -32768

超出范围的转换(精度丢失)

int 的值超出了 short 的范围,强制转换依然可以编译通过,但会发生“回绕”(wrap-around)“截断”(truncation)现象,高位(多余的16位)会被直接丢弃,只保留低16位,这会导致结果变得完全不可预测。

public class IntToShortOverflowExample {
    public static void main(String[] args) {
        int intValue1 = 32768; // short的最大值 + 1
        short shortValue1 = (short) intValue1;
        // 32768 的二进制是 0000 0000 0000 0000 1000 0000 0000 0000
        // 只保留低16位: 1000 0000 0000 0000,这表示 -32768
        System.out.println("溢出转换: " + intValue1 + " -> " + shortValue1);
        int intValue2 = 65535; // 2^16 - 1
        short shortValue2 = (short) intValue2;
        // 65535 的二进制是 0000 0000 0000 0000 1111 1111 1111 1111
        // 只保留低16位: 1111 1111 1111 1111,这表示 -1
        System.out.println("溢出转换: " + intValue2 + " -> " + shortValue2);
        int intValue3 = -32769; // short的最小值 - 1
        short shortValue3 = (short) intValue3;
        // -32769 的二进制补码是 1111 1111 1111 1111 1000 0000 0000 0001
        // 只保留低16位: 1000 0000 0000 0001,这表示 32767
        System.out.println("下溢转换: " + intValue3 + " -> " + shortValue3);
    }
}

输出:

java int转换short-图2
(图片来源网络,侵删)
溢出转换: 32768 -> -32768
溢出转换: 65535 -> -1
下溢转换: -32769 -> 32767

注意:这种“回绕”行为在某些底层编程(如游戏开发、图形学)中是有意为之的,但在大多数业务逻辑中,它是一个严重的 Bug。


编译时错误

如果在不进行强制转换的情况下直接赋值,并且值可能超出范围,编译器会直接报错。

public class IntToShortCompileError {
    public static void main(String[] args) {
        int largeInt = 50000;
        short myShort;
        // 下面这行代码会编译失败!
        // 错误信息: incompatible types: possible lossy conversion from int to short
        // myShort = largeInt;
        // 必须加上强制转换才能通过编译
        myShort = (short) largeInt;
        System.out.println("通过强制转换: " + myShort);
    }
}

编译错误:

IntToShortCompileError.java:8: 错误: 不兼容的类型: 从 int 转换到 short 可能会有损失
        myShort = largeInt;
                   ^
1 个错误

使用 Math.toIntExact() 进行安全转换 (Java 8+)

如果你想在转换前检查 int 的值是否在 short 范围内,并且如果不在就抛出一个异常,而不是静默地丢失数据,可以自己编写一个检查方法,或者使用 Math 类中的工具。

public class SafeIntToShortConversion {
    public static void main(String[] args) {
        int intValue = 100;
        // 安全转换方法
        short shortValue = safeIntToShort(intValue);
        System.out.println("安全转换成功: " + shortValue);
        int outOfRangeValue = 50000;
        try {
            safeIntToShort(outOfRangeValue);
        } catch (ArithmeticException e) {
            System.out.println("捕获到异常: " + e.getMessage());
        }
    }
    /**
     * 安全地将 int 转换为 short,如果超出范围则抛出异常。
     * @param value 要转换的 int 值
     * @return 转换后的 short 值
     * @throws ArithmeticException value 超出 short 范围
     */
    public static short safeIntToShort(int value) {
        if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
            throw new ArithmeticException("Integer value " + value + " is out of range for a short");
        }
        return (short) value;
    }
}

输出:

安全转换成功: 100
捕获到异常: Integer value 50000 is out of range for a short

总结与最佳实践

场景 方法 描述 风险
已知值在范围内 (short) myInt 使用强制类型转换。 无风险。
值可能超出范围 先检查,再转换 if (myInt >= Short.MIN_VALUE && myInt <= Short.MAX_VALUE) { ... } 推荐做法,可以避免静默的数据丢失,使 Bug 更容易被发现。
不关心数据丢失 (short) myInt 直接强制转换。 高风险myInt 超出范围,结果将是错误的,但程序不会报错。
明确想在下溢/溢出时抛出异常 safeIntToShort(myInt) 自定义方法,先检查范围,再转换,失败则抛出 ArithmeticException 最安全,适用于需要严格数据校验的场景。

核心建议永远不要盲目地进行 (short) int 转换,在转换前,你应该清楚地知道 int 变量的值是否在 short 的合法范围内,如果不确定,务必先进行检查。

分享:
扫描分享到社交APP
上一篇
下一篇