java - 从子类实例的(父类(super class))列表调用静态方法

标签 java android static-methods

假设我有一个基类 A (具有名为 normalInit() 的虚拟方法)和 300 个子类: A1, A2, A3, ...每个子类都有一个 staticInit()静态方法,加上 normalInit()覆盖。 (请不要问为什么;这是在生产软件中,已经给定的,无法更改设计以更好地重用。实际上,这些子类是由代码生成器生成的,但现在无关紧要。)

根据应用程序的不同执行,A1, A2, A3, ... 的(小)子集需要初始化。换句话说,有一些数据是特定Ai的所有实例的。共同分享或访问。显然,将这​​些实体定义为 static 是合理的。成员/方法(因为它们由 Ai 的所有实例共享)。

那么如何初始化这个子集的静态(并调用静态方法)呢?

简单来说,这不是静态初始化全部的解决方案 Ai子类,因为只需要一小部分(会浪费内存)。 static Java 中的行为显然为此提供了解决方案: static类的初始化器在第一次访问类时初始化(我在这里忽略了一些特殊情况,例如编译器内联原始最终静态变量,在这种情况下,技术上没有类访问,只是在源代码级别)。

问题是,我需要确定性(实际上是在预定义时间)静态初始化,因为它们的 static行为还访问应用程序的当前静态(全局)状态。所以static初始化程序不是一个选项,我需要 static方法,在适当的位置显式调用它们。

在相关应用程序中,必须在各种 Ai 的实例时执行此操作通过迭代 ArrayList<A> 来访问类,其中A是父类(super class)。

for (int i = 0; i < list.size(); ++i) {
        list[i].normalInit(args); // normalInit() is an instance method
    }

此列表包含 Ai实例(例如 950 个 A1 实例、1750 个 A2 实例等,以未排序的“随机”顺序)。

换句话说,我无权访问具体的类名(所以我不能只调用 A4.staticInit() ),因为我不知道哪个 Ai 。列表中有实例。 注意,我知道静态是在编译时绑定(bind)的,并且我确实知道这里不可能实现多态性,所以我不是问如何从上面的循环中调用静态方法!具体调用的实例(及其 Class )是在运行时决定的,由于动态调度,当 normalInit() 时被调用。

一个明显的解决方案是调用具体类'staticInit()方法来自 normalInit()覆盖:

public class A2 {   

    @Override
    public void normalInit(int[] args) {
        // ...       

        staticInit();
    }

    private static void staticInit() {
           if (!sStaticInitialized)  {
                sStaticInitialized = true;
                ...
           }
    }
}

为此,代码生成器模板生成 Ai必须修改子类。

但这(以及上面的代码)看起来并不是一个很好的解决方案。我理解整个应用程序设计是否存在一些缺陷,但即使这是您的观点,如果此类声明能够通过额外的(独立)建设性建议得到增强,我将不胜感激。对于上述问题有更好的解决方案/习惯用法吗?

最佳答案

好的,使用反射来回答它:

String classPrefixName = "com.your.company.A";
for (int i = 0; i< 300; i++) {
    Class<?> clazz = Class.forName(classPrefixName+i); //look for the class
    Method method = clazz.getDeclaredMethod("staticInit"); //look for the method
    method.invoke(null); //invoke(null), since it's a static method
}

这样您就不需要将静态方法包装在实例中。

关于java - 从子类实例的(父类(super class))列表调用静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14162558/

相关文章:

java - 如何使用 Vert.x 从 EventBus 中获取结果

java - 如何使用 Selenium - Junit 测试运行程序文件和 cucumber 选项为每次运行创建测试结果文件夹?

安卓Q : Permissions maintaining state after uninstall

android - 重复使用 "findViewById"还是存储View?

java - java继承中的隐藏方法

cocoa-bindings - 绑定(bind)到 Cocoa 中的类方法?

java - JAX-RS 方法没有 Path 或 HTTP 方法注释

java - 将 Owl 类转换为 java 类或 xml

android - 从 Google Places 结果中获取经度和纬度

java - 如何知道哪些子方法被称为静态父方法?