【问题标题】:Java, list of class typesJava,类类型列表
【发布时间】:2012-03-15 20:50:48
【问题描述】:

我正在开发一个 java 应用程序。这是一个抽象类 Model 和 2 个派生类 Model 1 和 Model 2。Model1 和 Model2 的行为不同,所以我想让用户从两者中选择一个模型。 它可以像这样实现:

Model model;
If(response==1){
    model = new Model1();
}else if(response==2){
    model = new Model2();
}

现在的问题是,如果我添加一个新类 Model3,我必须重写代码。 我可以创建一个列表,在其中添加每个类的实例,然后添加一个静态方法,该方法将返回该类的新实例,但我希望可以用更多的样式来完成。

是否可以创建一个列表来保存每个类的类型。从这个列表中,我可以创建一个菜单来选择一个模型,然后使用该类型来创建用户需要的类。

那么有没有可能,创建一个List<Class>,然后使用Class对象作为构造函数,来创建给定类的一个实例?

【问题讨论】:

    标签: java list class inheritance


    【解决方案1】:

    您可以创建suppliers的列表:

    static final List<Supplier<Model>> MODEL_MAKERS = ImmutableList.of(
        new Supplier<Model>() { public Model get() { return new Model1(); } },
        new Supplier<Model>() { public Model get() { return new Model2(); } },
        new Supplier<Model>() { public Model get() { return new Model3(); } }
    );
    

    您可以使用反射来解决问题,但这需要跳出 Java 的正常异常处理机制,需要零参数 public 构造函数和 public 类,这限制了代码在维护下如何以未经检查的方式更改javac,在这种情况下就没有必要了。

    【讨论】:

    • +1 表示不使用反射。但是,有时您必须这样做(例如,如果您在编译时不知道该类)
    • @StevenSchlansker,我同意反射的用途。我更喜欢将它限制在 Java 对象系统和其他系统之间的边界——文件系统、ORM、嵌入式脚本语言。如果您完全在 Java 中工作,通常会有更好的使用方法,并且不会影响维护人员重构代码、遵循程序流程等的能力。
    【解决方案2】:

    如果你确定它会有一个公共的无参数构造函数,你可以使用Class.newInstance()

    对于更复杂的用途,您可以找到带有Class.getConstructor(s)Constructor 对象,然后以这种方式调用它。

    一旦你有了它,将你的Classes 粘贴到Map 或做查找和创建实例的东西就相对容易了。

    【讨论】:

    • 不要使用newInstancejavadoc 明确警告:“请注意,此方法会传播空构造函数引发的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译器执行的编译时异常检查。”跨度>
    • 在某些情况下,这正是您想要的。不过,这绝对值得一提。
    【解决方案3】:

    是的,您可以使用 Class 上的newInstance() 方法来构造一个。不过它必须有一个无参数的构造函数。

    【讨论】:

    • 不要使用newInstancejavadoc 明确警告:“请注意,此方法会传播空构造函数引发的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译器执行的编译时异常检查。”跨度>
    • 如果你确信构造函数不会抛出异常就可以了。如果您从未调用任何可能引发异常的东西,那么您将永远无法完成任何编码...... :-)
    • 如果您确信构造函数不会抛出异常现在和维护中,那很好。
    • 我同意,如果可以的话,应该避免反思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 2011-01-31
    • 2010-12-02
    • 2013-10-19
    • 2017-01-28
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多