原始类型类的用途/目的是什么?

12
我最近学到JVM中有Class原始类型的表示。例如,int.classdouble.class,甚至是void.class
我不理解的是它们存在的原因。它们似乎没有任何功能作用。通过反射,我查找了这些类,它们没有构造函数、方法或字段。在所有情况下,它们似乎都是空的和无用的。原始类型变量甚至不是它们各自类的实例,如下面返回的结果为false:
int a = 3;
int.class.isInstance(a);

所以它们为什么存在?它们一定有一些作用,可能是为了编译器或其他什么东西,但无论是什么都完全超出了我的能力范围。甚至在Integer API中明确引用了int.class(对于每个基本类型及其相应的包装对象也是如此)。我甚至找不到任何关于它们存在的参考资料,更不用说它们的用途了,在JLS中也是如此。
2个回答

12

我不明白的是这些为什么在那里。

请考虑以下内容:

public int foo() {
    return 0;
}

...

Method method = someClass.getDeclaredMethod("foo");
Class<?> clazz = method.getReturnType();
没有 intClass 表示,那么上面的代码会返回什么?它不应该返回 Integer.class,因为它们并不是同一种东西。(想象一下如何区分重载的方法,一个有 int 参数,另一个有 Integer 参数。)
我之前使用过这些类来为通过反射调用的参数提供默认值。根据参数类型,我使用了 null 对于任何引用类型,以及对于每个基本类型的某个(显然是装箱的)基本值。

2
@Jeff:不,反射不仅仅是编译器使用的,对吧? - Jon Skeet
@Jeff:什么?不,我从来没有建议编译器会这样做。你从哪里得到这个想法的?我建议 int.class 和类似的东西对于反射 API 中的值非常有用,其中我们需要能够表示一个原始类型的返回类型或参数类型。请注意,我的答案甚至没有包含“编译器”这个词。 - Jon Skeet
2
一个用例:实现Swing TableModel的getColumnClass()函数。 - Puce
@Jeff:不,我提供了用户代码,其中调用了getDeclaredMethod()getReturnType()... - Jon Skeet

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层次结构难以理解。


虽然我同意 Type 很让人头疼,但我认为它与这个问题没有太大关系。换句话说:我相信即使在 Java 版本为 1.4 的时候,这个问题仍然有意义,但你的答案不会。 - Jon Skeet
"int.class"和""Class for int""从一开始就是廉价的肮脏技巧。在1.5之前这并不是太大的问题,但现在随着更多类型的引入,这个错误变得更加明显。 - irreputable
1
我确实更喜欢C#语法,但我仍然认为你的回答与问题没有太多关系,更像是一个离题的抱怨。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接