【问题标题】:Java list of uninstantiated classesJava 未实例化类列表
【发布时间】:2013-12-22 14:14:12
【问题描述】:

是否可以构造一个List<Object>,其中元素是未实例化的类,目的是获取列表元素之一并从该类运行静态方法或实例化该类的新实例?此外,如何做到这一点以及这样做是多么不可取(以及为什么)?

添加一些上下文:我想制作一个生成随机城市的应用程序,将建筑物放置在城市中,其中每个建筑物都是许多建筑物类之一的实例,每个都继承自一个抽象基类。要选择适合某块土地的建筑物,程序可能会遍历所有可能的建筑物类别的列表,检查是否可以满足该建筑物所需的参数(最小/最大高度、占地面积、形状等)或这些类可能以其他方式存储,可能使用映射或其他结构。底线是我需要将(引用?)存储到未实例化的类。

【问题讨论】:

  • 如果可行的话,我会列出“知道如何创建适当对象的工厂”——这实际上取决于这些数据的来源以及它的作用。
  • 最好是List<F extends FactoryInterface>
  • 这是一个非常好的建议,考虑到您在我为帖子添加上下文之前提出的建议,尤其令人印象深刻。我很可能会走这条路。谢谢你的想法。

标签: java class


【解决方案1】:

您不能存储类型,但可以为 JVM 加载的每个类存储 Class 对象。当 JVM 在类路径上加载和初始化一个类时,它会为该类创建一个 Class 对象。

Class 类使您可以访问许多实例方法,以便在您的程序上执行 reflection

另外,如何做到这一点以及这样做是多么不可取(以及为什么)?

例如

List<Class<?>> classes = new ArrayList<>();
classes.add(Example.class);

现在您可以浏览元素并根据您想要执行的操作调用不同的方法。如果你想创建一个新实例(并且你的类有一个无参数构造函数),你可以这样做

classes.get(0).newInstance();

如果您没有无参数构造函数,则需要从 Class 对象中获取 Constructor 引用。

如果您需要调用方法(无论是否static),您需要获得Method 引用。通读javadoc

这是多么不可取(以及为什么)?

有些事情你不能不反思,但通常不鼓励。


当您可以很好地使用Factory 模式在这种情况下实现您的目标时,您应该尽量减少使用反射。

User user2864740 suggests

我会有一个“知道如何创建 适当的对象”,如果可行的话 - 真的取决于这在哪里 数据的来源和作用。

【讨论】:

  • 这很好地回答了我的问题。 user2864740 有一个很好的建议(评论我上面的原始问题),我认为任何与我有相同问题的人都会感兴趣。我认为最好将该建议添加到您的答案的开头,因为正如您所说,“通常不鼓励”反思(现在我记得听到我的计算机科学教授几乎相同的警告,他非常简短地提到了反思)。
  • @BigEndian 用户建议的是在编译时绑定类的替代方法(在这种情况下可能更好)。反射将该绑定移动到运行时。
  • 是的,完全正确。在编译时做事可以说更干净、更健壮,这就是我非常喜欢这个建议的原因。
  • 我认为将它添加到答案中不会有什么坏处。它不是严格的主题,但它可能是一个非常有用的提示。不过那是你的选择。
  • @bigEndian 我希望他们给出完整的答案,但我现在已经链接了他们的评论。
【解决方案2】:

您可以像这样实例化 Class&lt;?&gt; 的实例 -

List<Class<?>> al = new ArrayList<>();
al.add(java.util.Date.class);
for (Class<?> cls : al) {
  try {
    Constructor<?> ctor = cls.getConstructor(null);
    Object o = ctor.newInstance(null);
    System.out.println(o);
  } catch (Exception e) {
    e.printStackTrace();
  } 
}

其中,当我刚刚运行它时,输出

Sun Dec 22 00:56:06 EST 2013

【讨论】:

  • 这对我很有帮助,我的场景包括我正在迭代的类都扩展了一个抽象类的复杂性,我可以将Object o 转换为,然后调用抽象方法。我仍然怀疑我的模式,但你的回答帮助我结束了循环。
猜你喜欢
  • 1970-01-01
  • 2021-05-14
  • 2014-04-04
  • 2020-07-29
  • 2020-02-07
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多