当加载特定类(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.class
? Class.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/