所以你想得到包装类类型,好的。
概要
我们正在检索一个字段,然后发现它包含一个原始类型。
Field f = getTheField(); // Dummy method that returns my Field
Class<?> c = f.getType();
但相反,我们想要包装器类型。
Java中的原始类型
现在您已经发现原始类唯一有用的就是返回 true for c.isPrimitive();
。
来自wiki 书籍 - java 编程:
原始类型是 Java 语言中最基本的数据类型。有 8 个: boolean 、 byte 、 char 、 short 、 int 、 long 、 float 和 double 。这些类型充当 Java 中数据操作的构建块。这样的类型只有一个目的——包含一种纯粹的、简单的值。
试图以任何其他方式使用它们,你会受到很大的伤害。
无法创建基元的新实例。
Field f = getTheField();
Class<?> c = f.getType();
Object wrapper = c.newInstance();
// java.lang.InstantiationException thrown: int
// at Class.newInstance (Class.java:545)
无法转换为原始类型。
Field f = getTheField();
Class<?> c = f.getType();
Object wrapper = c.cast(0);
// java.lang.ClassCastException thrown: Cannot cast java.lang.Integer to int
// at Class.cast (Class.java:3578)
可以强制转换为空包装器类型。是的!\o/
Field f = getTheField();
Class<?> c = f.getType();
Object wrapper = c.cast(null);
没有例外,变量wrapper
是类型class java.lang.Integer
,但值为null
,对我们有很多好处。
基元甚至没有从包装器继承。
boolean isSuperClass = Integer.class.isAssignableFrom(int.class); // false
这显然没有让我们有任何进展,让我们从问题中退后一步,看看更大的图景。
当你一开始没有成功...
让我们回顾一下:我们正在检索一个必须来自某个地方的字段,因为java.lang.reflect.Field
它被标记为 final 并且不公开任何公共构造函数。
如果我们要填补空白,它可能看起来像这样。
public class Simple {
public static int field;
public static void main(String[] args) {
Field f = Simple.class.getField("field"); // Actual method that returns my Field
Class<?> c = f.getType();
}
}
与其与机器对抗,不如与它一起工作。原语的好处之一是它们将初始化为默认值0
而不是null
. 让我们看看我们是否可以使用它。
从包装的实例中获取包装类。
public class Simple {
public static int field;
public static void main(String[] args) {
Simple boxer = new Simple();
Field f = Simple.class.getField("field");
Object wrapped = f.get(null); // Integer value 0
Class<?> c = wrapped.getClass(); // class java.lang.Integer
}
}
这比以前容易多了,我们甚至不需要做任何事情,一切都为我们做好了。不试图逆流而上的另一个好处。
让我们对此进行改进,重构并通过提取方法使其更具可重用性。
实施手动装箱方法。
public class Simple {
public static int field;
public static <T> T wrap(T t) {
return t;
}
public static void main(String[] args) {
Field f = Simple.class.getField("field");
Class<?> c = Simple.wrap(f.get(null)).getClass(); // class java.lang.Integer
}
}
一个简单的原始包装,无需查看类型或使用查找表,因为 java 已经这样做了。
简单的解决方案
Field f = getTheField(); // Dummy method that returns my Field
Class<?> c = f.get(null).getClass();
或者,如果字段不是静态的,您可以将 null 替换为实例。
开心!