问题描述
我想写一些这样的代码:
I would like to write some code like this:
Object o = ...;
String oTypeName = o.getClass().getName();
//on the other side of the wire:
Class<?> oClass = Class.forName(oTypeName);
Object oAgain = oClass.newInstance();
但是,javadoc 中并不清楚我应该使用哪种方法来初始化 oTypeName
,即哪种方法会产生 Class.forName()
:
However, it's not clear from the javadoc which method I should use to initialize oTypeName
, i.e. which method will produce the expected input to Class.forName()
:
getCanonicalName()
: "返回 Java 语言规范定义的底层类的规范名称.如果底层类没有规范名称(即,如果它是本地或匿名类或其组件类型没有规范名称的数组)."getName()
: "以String形式返回此Class对象所代表的实体(类、接口、数组类、原始类型或void)的名称.如果该类对象代表的引用类型为不是数组类型,则返回类的二进制名称,如 Java™ 语言规范所指定."getTypeName()
:返回此类型名称的信息字符串."
很明显,我不想要其中任何一个:
It's fairly obvious that I don't want either of these:
getSimpleName()
:返回源代码中给出的底层类的简单名称."toString()
: "字符串表示是字符串"class"或"interface",后跟一个空格,然后是getName返回格式的类的全限定名"
我不希望这适用于原始类型.如果它不适用于数组也没关系.我主要关心的是嵌套类和 Foo.Bar
与 Foo$Bar
.
I don't expect this to work for primitive types. It's okay if it won't work for arrays. The main thing I'm concerned about is nested classes and Foo.Bar
vs. Foo$Bar
.
推荐答案
明确的答案是 getName()
.虽然有点隐藏,但这在 forName(className, initialize, loader)
:
The definite answer is getName()
. Although a bit hidden, this is specified in the Javadoc of the overload of forName(className, initialize, loader)
:
给定类或接口的完全限定名称(与 getName
返回的格式相同),此方法尝试定位、加载和链接类或接口.
并且还指定调用forName(className)
等价于调用这个重载,有默认值:
And it is also specified that calling forName(className)
is equivalent to calling this overload, with default values:
调用这个方法相当于:
Class.forName(className, true, currentLoader)
其中 currentLoader 表示当前类的定义类加载器.
where currentLoader denotes the defining class loader of the current class.
这是一个示例代码,显示它适用于嵌套类、本地类、匿名类、原始或对象数组.它不适用于基元,因为 Class.forName
不处理基元类.
public class Main {
public static void main(String... args) throws ClassNotFoundException {
class LocalClass {}
System.out.println(Class.forName(name(StaticNestedClass.class))); //static nested class
System.out.println(Class.forName(name(InnerClass.class))); // inner class
System.out.println(Class.forName(name(Integer[].class))); // object array
System.out.println(Class.forName(name(int[].class))); // primitive array
System.out.println(Class.forName(name(List.class))); // interface
System.out.println(Class.forName(name(LocalClass.class))); // local class
System.out.println(Class.forName(name(new Object(){}.getClass()))); // anonymous class
}
private static String name(Class<?> clazz) {
return clazz.getName();
}
public static class StaticNestedClass {}
public class InnerClass {}
}
这篇关于哪个 java.lang.Class 方法为 Class.forName() 生成正确的输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!