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
}