当前位置: 首页 > 知识库问答 >
问题:

哪个java.lang.类方法为Class.forName()生成正确的输入?

澹台胜
2023-03-14

我想写一些这样的代码:

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,即哪个方法将生成类的预期输入。forName()

  • getCanonicalName():“返回Java语言规范定义的基础类的标准名称。如果基础类没有标准名称(即,如果它是本地或匿名类,或者组件类型没有标准名称的数组),则返回null。”
  • getName():“以字符串形式返回由该类对象表示的实体(类、接口、数组类、基元类型或void)的名称。如果该类对象表示的引用类型不是数组类型,则返回由Java™ 语言规范。“
  • getTypeName():“返回此类型名称的信息字符串。”

很明显,我不想要这些:

  • getSimpleName():返回源代码中给出的基础类的简单名称。
  • toString():字符串表示是字符串类或接口,后跟空格,然后是getName返回的格式中类的完全限定名称

我不认为这适用于基本类型。如果它对数组不起作用,也没关系。我最关心的是嵌套类和Foo。条形码与Foo$Bar的对比。


共有3个答案

仇迪
2023-03-14

我总是使用getCanonicalName()内部对象(如您的Foo$Bar如果静态公共vs内联实现)也可以构建

您还可以使用原语使其工作。'例如,int.class确实存在。但是,您可能需要检查基本类,并生成对象实例(Integer vs int),然后调用类似intValue()的访问器。正因为如此,我使用了很多对象实例和基本体,但我想这只是我的偏好。

邵阳德
2023-03-14

它看起来像是getName()getTypeName()工作,至少在简单的情况下是这样的:

public final class ForNameTest{

    public static void main(String[] args) throws Exception{
        Object o = new Foo();
        System.out.println("class is: " + o.getClass());

        for(String getterMethodName : Arrays.asList("getName", "getTypeName", "getCanonicalName")){
            Method m = Class.class.getMethod(getterMethodName);
            String oTypeName = m.invoke(o.getClass()).toString();
            System.out.println(getterMethodName + " yields " + oTypeName);
            try{
                Class<?> oType = Class.forName(oTypeName);
                Object oAgain = oType.newInstance();
                System.out.println(" ... and it works: " + oAgain);
            } catch (Exception e){
                System.err.println(" ... and it fails: " + e);
            }
        }
    }

    public static class Foo{}
}

产出为:

class is: class ForNameTest$Foo
getName yields ForNameTest$Foo
 ... and it works: ForNameTest$Foo@4554617c
getTypeName yields ForNameTest$Foo
 ... and it works: ForNameTest$Foo@74a14482
getCanonicalName yields ForNameTest.Foo
 ... and it fails: java.lang.ClassNotFoundException: ForNameTest.Foo
阳兴朝
2023-03-14

确切的答案是getName()。虽然有点隐藏,但这是在forName(className,initialize,loader)重载的Javadoc中指定的。

给定类或接口的完全限定名(与getName返回的格式相同),此方法尝试定位、加载和链接类或接口。

并且还指定调用forName(class Name)等效于调用此重载,默认值为:

调用此方法相当于:

Class.forName(className, true, currentLoader) 

其中currentLoader表示当前类的定义类加载器。

下面是一个示例代码,显示它适用于嵌套类、本地类、匿名类、基元或对象数组。它不适用于原语,因为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中,main() 方法是 Java 应用程序的入口方法,程序在运行的时候,第一个执行的方法就是 main() 方法。main() 方法和其他的方法有很大的不同。   每个类可以有也可以没有main方法。

  • 我真的很感激有人能帮忙... 我为两个智能合约(SheepHelper和SheepFactory)生成了java智能合约包装器。当我尝试在android中使用这些方法时,我只能返回TransactionReciep对象(即使是视图函数) 因此,我无法读取智能合约中包含的任何数据。 生成包装器方法的方式有问题吗?/这是web3j问题吗(下面的代码) 我使用的版本可能有问题吗?(Web3j版本为:,杂

  • 问题内容: 我在Go中编写了一个简短的程序,可以通过stdin提供的密码生成bcrypt密码哈希。下面的最小示例: 在另一个程序(Go Web服务器)中,我接受来自HTTP 请求的用户密码,并针对由以上代码生成的哈希进行测试,并将其保存到启动时加载的配置文件中,如下所示: 但是,当我知道正确时,这将报告失败。经过一番调查后,我发现当我使用此网站测试我的值时,上面的内容最初生成了错误的输出:http

  • 我使用@ControllerAdvision在Spring Boot控制器中捕获异常。在@ExceptionHandler中,我可以手动指定数量有限的异常及其状态代码。 我的问题是如何处理所有其他异常及其状态?

  • 我知道以前有人问过这个问题,但答案是矛盾的,我很困惑,所以请不要炒我鱿鱼。 我希望在整个应用程序中有一个可重用的子类。我想用一个nib文件来描述这个接口。 现在让我们假设它是一个加载指示器视图,其中包含一个活动指示器。我想在某个事件上实例化此视图并在视图控制器的视图中设置动画。我可以用编程的方式描述视图的接口,通过编程创建元素,并在init方法中设置它们的框架等等。 但是,我如何使用笔尖来实现这一

  • 我试图在spring boot应用程序中使用swagger注释从Java代码中获取swagger规范(yaml)。我对模型进行注释,然后运行springboot应用程序,然后从http://localhost:8080/v2/api-文档。 我的模型如下所示: 我想为此创建正确的swagger yaml斑点。当我访问自动提供yaml的swagger UI时,我期待下面的内容。 注意dateOfBi