之前写参数校验的时候将字段的长度写成了一个常量,习惯了用包装类型,于是乎有了类似(以下截图只是为了复现这个问题刚特意改的)如下的代码:
结果项目编译报错,提示我这里传入的不是一个常量:
心想“我这个字段都用 static
和 final
修饰了,怎么就不是常量了?”带着这个“疑问”点开 @Size
注解的定义:
发现其中 min 和 max 字段的定义是 int
基本类型,并不是 Integer
包装类型,再想到 Java 中基本类型与其对应的包装类型之间的自动装箱和拆箱机制,一下就明白了。我定义的是 Integer 类型的常量,当赋值给 int 类型的字段时,Java 编译器会自动将其拆箱为 int 类型。而这个拆箱的实现方式,其实就是调用 Integer 对象的 .intValue()
方法(其他几个包装类型同理)。
所以我们定义的 Integer “常量”对编译器来说实际上是 Integer.intValue() 这样一个方法调用,明显已经不是一个常量表达式了。
知道原因后,将 Integer 修改为 int:
再来编译试试,发现这下编译通过了:
我们可以通过以下例子来验证上面的问题:
编译后通过 javap
命令查看编译后的字节码,可以看出来,自动装箱实际上就是调用的 Integer.valueOf() 方法,拆箱就是调用的 Integer.intValue() 方法:
这样也就能明白为什么将一个 Integer 常量赋值给 int 时就不是常量了。
0 条评论