繁体   English   中英

Java:遍历嵌套类

[英]Java: Iterate through Nested Classes

目前,我在外部 class 中有许多嵌套类。 每个嵌套的 class 都有一个覆盖的toString方法。 我的目标是遍历这些嵌套类以访问被覆盖的toString返回的值,而无需初始化每个嵌套的 class。 我尝试遍历Class#getDeclaredClasses返回的数组

简化的外部 class:

class MyClass {
    static class NestedClassOne {
        @Override
        public String toString() {return "One";}
    }
    static class NestedClassTwo {
        @Override
        public String toString() {return "Two";}
    }
}

我尝试过的方法,使用Class#getDeclaredClasses数组:

        for (Class<?> NestedClass : MyClass.class.getDeclaredClasses()) {
            System.out.println(NestedClass.toString());
        }

令我沮丧的是,这种方法只打印以下内容:

class ... MyClass$NestedClassTwo
class ... MyClass$NestedClassOne

您的toString()直接在 class object 上调用。 即,它调用Class<T>.toString()而不是NestedClassOne.toString() 为此,您需要使用反射:

  Class<NestedClassOne> clazz = NestedClassOne.class;
  Method method = clazz.getMethod( "toString" );
  NestedClassOne obj = clazz.newInstance();

  Object result = method.invoke( obj );
  System.out.println( result );

但是,我将重复我的评论:

这听起来是个坏主意。 你真的不应该像这样使用反射。 enum或类似的东西可能更合适。

它只是一种明显的超级脆弱。 它会引发许多异常,而枚举不会。 如果代码结构发生变化(例如更改为不同的构造函数),它就会中断。 如果方法名称发生更改,编译器将无法检测到它。 等等。我不想维护按您要求的方式工作的代码。

我的目标是 1) 遍历这些嵌套类 2) 访问被覆盖的toString返回的值,而不初始化每个嵌套的 class

你正在做的第一部分。 第二部分是不可能的。

您尝试调用的toString()方法是实例方法。

  • 在创建实例之前,您不能调用实例方法。
  • 如果不触发1 class 的 static 初始化,则无法创建 class 的实例。

您尝试的代码实际上是在调用Class对象上的toString()方法。 这为您提供了类的名称

@markspace 的答案显示了如何创建实例并通过反射调用toString()方法。 需要注意的是,它假定每个 class 都有一个无参数构造函数,并且创建实例没有不良副作用。


1 - 有些场景涉及具有循环依赖关系的类,其中 class 的实例可能在其 static 初始化完成之前创建。


我同意@markspace 的评论。 我不确定这样做的真正目的是什么,但可能有比调用toString()方法更好(更健壮)的方法。 (例如......使用具有运行时保留的自定义注释。)

即使没有,不初始化类的约束对我来说似乎是人为的:这是过早的优化吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM