Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从子类实例的(超类)列表调用静态方法_Java_Android_Static Methods - Fatal编程技术网

Java 从子类实例的(超类)列表调用静态方法

Java 从子类实例的(超类)列表调用静态方法,java,android,static-methods,Java,Android,Static Methods,假设我有一个基类a(带有一个名为normalInit())的虚拟方法)和300个子类:A1、A2、A3、这些子类中的每个都有一个staticInit()静态方法,外加一个normalInit()覆盖。(请不要问为什么;这是一个生产软件,已经给出,不能改变设计以更好地重用。实际上,这些子类是由代码生成器生成的,但现在这与此无关。) 根据应用程序的不同执行,需要初始化A1、A2、A3、…的(小)子集。换句话说,有些数据是特定Ai的所有实例共同共享或访问的。显然,将这些实体定义并视为静态成员/方法是合

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

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

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

简而言之,它不是静态初始化所有Ai子类的解决方案,因为只需要一小部分(这将浪费内存)。Java中的
static
行为显然提供了一个解决方案:类的
static
初始值设定项在第一次访问类时初始化(这里我忽略了一些特殊情况,例如,编译器内联的优先级最终静态,在这种情况下,技术上没有类访问,只是在源代码级别)

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

在所讨论的应用程序中,当通过迭代
ArrayList
访问各种
Ai
类的实例时,必须执行此操作,其中
A
是超类

for (int i = 0; i < list.size(); ++i) {
        list[i].normalInit(args); // normalInit() is an instance method
    }
为此,必须修改生成
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
}
String classPrefixName=“com.your.company.A”;
对于(int i=0;i<300;i++){
Class clazz=Class.forName(classPrefixName+i);//查找类
Method Method=clazz.getDeclaredMethod(“staticInit”);//查找该方法
invoke(null);//invoke(null),因为它是一个静态方法
}

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

您尝试过反射吗?从由类名定义为字符串的不同类调用静态方法…这将是一个类似的解决方案(只是速度较慢)作为当前的一个,不是吗?我仍然需要存储哪些Ai类名已经通过反射访问过(以调用它们的静态方法)。使用反射,您可以直接访问静态方法,而无需包装它。缺点是您必须将类的名称设为字符串[]在迭代之前。回答某人的问题:超类不能调用staticInit(),因为staticInit()特定于A1、A2、A+,它们每个都有一个不同的和自己的staticInit()。@ThomasCalc反射速度较慢,但1000次调用不会产生明显的差异(也就是说,我们这里说的是毫秒,如果不是微秒的话)。例如,请参阅,了解通过反射调用方法的成本(在您的案例中,查找方法需要更多时间)。
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
}