java中short类型取值范围为-32768到32767,防御性编程需在解析输入时立即校验范围,使用long.parselong()转long再比对short.min_value和max_value,越界则抛illegalargumentexception。

Java中short类型取值范围是-32768到32767(即Short.MIN_VALUE到Short.MAX_VALUE)。防御性编程的关键不是等数据“溢出”后再处理(Java整数溢出不会抛异常),而是**在解析或接收输入的第一时间就校验范围,拒绝非法值**。
从字符串输入解析时主动校验范围
用户输入(如HTTP参数、命令行、配置文件)通常是字符串,需转为short。不要直接用Short.parseShort()后赋值——它可能成功解析一个超出short范围的数字(比如"100000"会静默溢出为-31072),应先判断数值是否在合法区间内:
- 用
Long.parseLong()转成long(避免int/short自身溢出干扰判断) - 再与
Short.MIN_VALUE和Short.MAX_VALUE比较 - 仅当在范围内才转为
short,否则抛出带上下文的异常(如IllegalArgumentException)
public static short parseShortSafely(String input) {
if (input == null || input.trim().isEmpty()) {
throw new IllegalArgumentException("Input cannot be null or empty");
}
try {
long value = Long.parseLong(input.trim());
if (value Short.MAX_VALUE) {
throw new IllegalArgumentException(
String.format("Value '%s' is out of short range [%d, %d]",
input, Short.MIN_VALUE, Short.MAX_VALUE)
);
}
return (short) value;
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid number format: " + input, e);
}
}
方法入参层面做显式范围断言
若接口接收int或long型参数但语义上应为short(如ID、状态码),应在方法开头校验,而非依赖调用方传入short:
- 用
Objects.requireNonNull()防null(如参数为包装类) - 对原始类型参数,直接比较边界值
- 推荐使用
java.util.Objects.checkIndex()风格自定义校验工具方法
public void processTemperature(int celsius) {
if (celsius Short.MAX_VALUE) {
throw new IllegalArgumentException(
String.format("Temperature %d exceeds short capacity", celsius)
);
}
short safeTemp = (short) celsius; // 此时可安全强转
// ...后续逻辑
}
JSON反序列化时借助库的范围约束能力
使用Jackson或Gson时,避免让框架自动把超限数字映射为short字段(同样存在静默溢出)。可通过以下方式拦截:
- Jackson:用
@JsonCreator配合自定义构造器,在反序列化时调用前述parseShortSafely() - Gson:注册
TypeAdapter<short></short>,重写read()方法做范围检查 - 或统一用
Integer接收,再在业务层校验转换(更灵活,便于日志和监控)
单元测试必须覆盖边界和越界场景
防御性代码的有效性依赖测试验证。每个涉及short输入的路径都应有明确的边界测试用例:
- 正常值:
"-32768"、"0"、"32767" - 越界值:
"-32769"、"32768"、极大值如"999999" - 异常输入:
null、空字符串、非数字字符 - 验证是否抛出预期异常,且异常消息包含关键信息(如实际值、允许范围)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











