【问题标题】:Invoking a static method over a list of "Class" objects [closed]在“类”对象列表上调用静态方法 [关闭]
【发布时间】:2021-12-10 00:53:47
【问题描述】:

我的问题更像是个人的思维挑战而不是生产目的......这意味着尽管有明显更好的方法可以实现我的目标*,但我很好奇 - AND IF - 我可以这样做。
*因此我对其他方式不感兴趣

我想在一个列表中“注册”几个类对象(Foo.class、Bar.class 等),它们共享一个从公共父类继承的公共静态方法。 然后我想遍历这个列表,并调用那个静态方法。

以下代码确实是错误的,但它至少可以显示我想要实现的目标:

======== 类定义

public class SomeGenericClass {
   public abstract static String getType();
}
public class SomeSpecializedClassA extends SomeGenericClass{
   public static String getType(){
      return "I am of type A";
   }
}
public class SomeSpecializedClassB extends SomeGenericClass{
   public static String getType(){
      return "I am of type B";
   }
}

======== 主要

class Main{

    void main(){
        List<Class<SomeGenericClass>> classes = new ArrayList<Class<SomeGenericClass>> ();
        classes.add(SomeSpecializedClassA.class);
        classes.add(SomeSpecializedClassB.class);
        
        for((SomeGenericClass.class)Class c : classes){
            System.out.println(c.getMethod("getType", null).invoke(null, null));
        }
    }

}

========

有什么想法吗?

【问题讨论】:

  • 没有抽象的静态方法。
  • 试试这个库asm.ow2.io
  • 试试这个库asm.ow2.io lombok 等工具使用这个库将方法注入到类中。相关的 Maven 存储库。 mvnrepository.com/artifact/asm/asm/3.3.1
  • 您无需做太多事情即可使您的代码正常工作。而不是abstract 在调用SomeGenericClass.getType() 时抛出异常。现在为您的其他类返回类型。静态方法不会被继承,但是在子类中定义同名的静态方法会隐藏父类的方法。但总的来说,整个方法似乎是错误的。很少有充分的理由在代码中使用 getType 或 instanceof 之类的方法。

标签: java class abstract-class static-methods


【解决方案1】:

共享从一个公共父类继承的公共静态方法。

这是不可能的;静态方法不“做”继承,因此它们被称为静态方法。 没有方法可以指定给定类遵守规范,其中“规范”涉及“具有静态方法 XYZ”。

为什么你认为 java 有“工厂”的陈词滥调?工厂只是一个容器概念,其中一个类的单个实例是您询问有关另一个类的概念的地方:“PersonFactory”是一个通常只存在一个实例的类,它通常回答有关人员的问题.最常见的是构造函数(它也不“做”规范/接口),但其他任何事情也一样。

然后我想遍历这个列表,并调用那个静态方法。

反射可以做到这一点。这将是可怕的代码风格,难以维护,而且完全是错误的方法。你问我:“我可以有一把枪,因为我的左脚趾上有一只讨厌的蚊子”,那就是火箭筒。如果你想拿走它,然后撕掉,好吧。你的葬礼。

那么有什么更好的方法呢?

为什么“静态”在这里很重要?它不是。注册“TypeOracle”对象:

public interface CommandHandlerFactory {
    String getCommand();
    CommandHandler makeHandler();
}

public interface CommandHandler {
    void handleCommand(UserInfo sendingUser, String cmdData);
}
public class WelcomeHandler {
    @Override
    public void handleCommand(UserInfo sendingUser, String cmdData) {
      sendMsg("Well hello there, " + sendingUser.getUserName() + "!");
    }
}

channelBot.registerHandler(new CommandHandlerFactory() {
  @Override
  public String getCommand() {
    return "/hello";
  }

  @Override
  public CommandHandler makeHandler() {
    return new WelcomeHandler();
  }
}

这就是你如何以一种非吹牛的方式做到这一点的。

注意:对您的问题的评论建议使用 asm。这是一个完全荒谬的评论; ASM 与此无关,无法帮助您。忽略此评论。

【讨论】:

  • 虽然您不能在没有反射的情况下使用类列表,但您当然可以存储类中的 Runnable 方法引用列表,这可能足够接近。
  • @rzwitserloot 请注意,我的问题是基本的好奇心,而不是编写生产代码的方法。你的回答确实指出了我的许多错误(恰到好处的讽刺和讽刺使它更清楚),你的选择很有趣(至少因为我不知道这样的模式)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2011-07-21
  • 1970-01-01
相关资源
最近更新 更多