本文介绍了哪个 java.lang.Class 方法为 Class.forName() 生成正确的输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一些这样的代码:

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.BarFoo$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() 生成正确的输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 19:47