java - 为什么 getConstructor 反射 api 需要 int.class 参数?

标签 java reflection

当加载特定类(X)时,

Class 实例将在每种类型的常量池中创建。

javac 将此语法 int.class 编译为指向 Integer.TYPE 指向的对象。

下面的代码,访问class X的parameterise(int)构造函数。

Class c = X.class;
Constructor cons = c.getConstructor(int.class);
cons.newInstance(10);

在上面的代码中,我不明白 int.class 参数的作用。

为什么getConstructor没有设计为接受String类型参数“int”而不是int.classClass.forName() 的参数就是一个例子。

最佳答案

首先,Class是专用于某种目的的类型。有很多类,我们可以简单地将其实例替换为 String如果我们接受一点歧义和可能的性能损失,它就会起作用。例如。为什么使用数字而不是 String包含其表示的 s,或者为什么使用 enum s 而不是他们的名字?因此,拥有专用类型的实例可确保创建、查找、解析或获取该实例所需的任何操作已成功执行。

所以有一个 Class代表 int.class 的对象,您知道您指的是现有类型,您不能对 String 说这些类型"int" 。一个String参数不一定引用现有类型 - 它甚至不必包含有效名称。如果您查找具有两个 int 的构造函数参数,传递 "int", "int"意味着验证正确性和查找适当类型的整个工作要进行两次。等等……

并且,由于 Java 编程语言的限制不适用于 JVM,因此 String是模棱两可的。尚不清楚是否"int"指的是 class命名int或原始类型 int 。请注意,当您调用loadClass("int")时在ClassLoader上,始终假设您指的是 class命名int因为该方法不适合查找原始类型。这就是 int.class 的原因被编译为访问 Integer.TYPE ,因为原始类型不能以与引用类型相同的方式查找。

此外,正如已经解释过的 here ,名称在运行时是不明确的,因为可以有多个具有相同名称的类,并由不同的 ClassLoader 定义。 s。

参见JVMS §5.3 “Creation and Loading” :

At run time, a class or interface is determined not by its name alone, but by a pair: its binary name (§4.2.1) and its defining class loader.

还有JLS §12.2 “Loading of Classes and Interfaces”

Well-behaved class loaders maintain these properties:

  • Given the same name, a good class loader should always return the same class object.

  • If a class loader L1 delegates loading of a class C to another loader L2, then for any type T that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object.

A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java Virtual Machine guards against this.

关于java - 为什么 getConstructor 反射 api 需要 int.class 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31240796/

相关文章:

java - 如何在 InputStream 上加锁并在读取完成后释放

java - IndexOutOfBounds,当它不应该的时候

java - 从类名中检索类的实例

c# - 创建现有程序集/模块的动态副本

c# - 如何使用反射来确定属性上是否存在属性?

c# - 使用反射和 C# 调用静态方法时遇到问题

java - 如何强制属性等于常量值之一(在 Java 中)?

java - 在 Windows Server 2012 中为 Tomcat 7.0 设置堆大小(以 GB 为单位)

java - 验证 Swagger

c# - 无法在运行时访问 SuppressMessage 属性