因魔头s 2024-06-14 10:04 采纳率: 80%
浏览 3
已结题

java工厂模式获取不到类中方法

程序启动时加载配置中所有转换格式,使用简单工厂模式,创建后获取不到方法,以下是代码

工厂类:

public class DataFormatterFactory {

    public static IDataFormatter create(String formatterName, String config){
            switch(formatterName){
                case "com.nsbox.mqtt.conrtoller.data.factory.impl.DataFormatterA":
                    return new DataFormatterA();
                case "com.nsbox.mqtt.conrtoller.data.factory.impl.DataFormatterB":
                    return new DataFormatterB();
            }
        return null;
    }
}

抽象类:

public interface IDataFormatter {
    DataPoint format(String raw_data);
}

实现A:

public class DataFormatterA implements IDataFormatter {

    @Override
    public DataPoint format(String raw_data) {
        System.out.println("formatterA");
        return new DataPoint();
    }
}

实现B:

public class DataFormatterB implements IDataFormatter {

    @Override
    public DataPoint format(String raw_data) {
        System.out.println("formatterB");
        return new DataPoint();
    }
}

调用类:

private List<IDataFormatter> formatters = new ArrayList<>();
private void createFormatters() {
        List<BoxObj> boxList = formatterConfig.getBoxList();
        for (BoxObj box:boxList){
            IDataFormatter formatter = DataFormatterFactory.create(box.getClassName(), box.getConfig());
            formatters.add(formatter);
        }
    }
这里formatters集合中为两个空的类,想要集合中存储这两个类,并且使用类中方法。
  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-14 10:04
    关注

    引自免费微信小程序:皆我百晓生

    从你提供的代码来看,主要的问题在于DataFormatterFactory中的create方法通过硬编码的方式来决定实例化哪个类。这不仅限制了扩展性,也使得代码难以维护。更好的做法是利用Java反射机制来动态地创建类的实例。这样,即使在运行时才知道具体的类名,也能正确地创建出相应的对象。

    下面是修改后的DataFormatterFactory,使用反射来创建对象:

    import java.lang.reflect.Constructor;
    
    public class DataFormatterFactory {
    
        public static IDataFormatter create(String formatterClassName) {
            try {
                // 动态加载类
                Class<?> clazz = Class.forName(formatterClassName);
                // 检查类是否实现了IDataFormatter接口
                if (IDataFormatter.class.isAssignableFrom(clazz)) {
                    // 获取构造器并创建实例
                    Constructor<?> constructor = clazz.getConstructor();
                    return (IDataFormatter) constructor.newInstance();
                } else {
                    throw new IllegalArgumentException("Class does not implement IDataFormatter");
                }
            } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
                // 处理异常
                e.printStackTrace();
                return null;
            }
        }
    }
    

    这样修改后,createFormatters方法可以正常工作,因为DataFormatterFactory.create现在能根据传入的类名动态创建对应的IDataFormatter实例。

    此外,为了确保安全性和类型兼容性,create方法中增加了对类是否实现IDataFormatter接口的检查。如果传入的类名不是IDataFormatter的实现,则会抛出异常。

    在实际应用中,你可能还需要考虑如何处理更复杂的构造函数(如果有多个参数),以及如何更好地管理这些动态创建的对象的生命周期等问题。但对于当前的问题,上述修改应该足够解决你的需求。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月22日
  • 已采纳回答 6月14日
  • 创建了问题 6月14日