我最近了解到JVM中的原始类型有Class个表示。例如,int.class
,double.class
,甚至是void.class
。
我不明白为什么这些都存在。他们似乎没有任何功能。使用反射,我搜索了类,它们没有构造函数,没有方法,也没有字段。出于所有意图和目的,它们似乎空洞无用。原始类型变量甚至不是它们各自类的实例,如下所示返回false:
int a = 3;
int.class.isInstance(a);
那为什么它们存在?它们必须用于某种目的,可能用于编译器或其他东西,但无论它是什么都完全超出我的意义。在Integer API中甚至有int.class
的明确引用(同样对于每个基本类型及其各自的包装对象)。在JLS中,我无法找到任何关于它们存在的参考,更不用说它们的用途了。
答案 0 :(得分:12)
我不明白为什么会有这些。
请考虑以下事项:
public int foo() {
return 0;
}
...
Method method = someClass.getDeclaredMethod("foo");
Class<?> clazz = method.getReturnType();
如果没有Class
代表int
,上述内容会返回什么?它不应该返回Integer.class
,因为它们不是相同的东西。 (想象一下,尝试区分重载的方法,一个int
和一个Integer
参数。)
我之前使用过这些类,通过反射调用它们时为参数提供默认值。根据参数类型,我使用了null
作为任何引用类型,并为每种基本类型使用了一些(明显的盒装)原始值。
答案 1 :(得分:2)
这是一个廉价的解决方案,结果很糟糕。
在1.5之前,Java类型可以归类为
java type
primitive type
reference type
class type (including interface)
array type
理想情况下,java反射应提供镜像这5种类型的5个概念。但是他们使用单个Class
来表示它们,包括基元和数组类型。所以Class
并不一定意味着一个类。
那仍然可以管理。但是在1.5之后,Java类型变得更加复杂,因此引入了新的Type
。不幸的是,他们决定让Class
成为Type
的子类型,而不是使用直接反映语言规范的新的干净层次结构。不仅引入了旧的混乱,它还会产生一些新的混乱,并且整个Type
层次结构是难以理解的。