【问题标题】:In Java: How to access static property of dynamically referenced class?在 Java 中:如何访问动态引用类的静态属性?
【发布时间】:2011-02-07 20:26:55
【问题描述】:

在 Java 中:如何访问动态引用类的静态属性? 我举一个简短的例子:

AppleTree.areTheyAllGrown=true;

我只是想动态引用静态属性“areTheyAllGrown”的类。这个静态属性可以是 AppleTree 的成员,也可以是其他类的成员,当然也有相同的命名静态属性:“areTheyAllGrown” .

只要我的应用程序逻辑需要我有许多其他树类型,如 CherryTree、ApricotTree 等,这意味着接口 TreeBehaviour 将不足以解决问题,因为通过专门设置 AppleTree 的“areTheyAllGrown”,我想标记比方说:只有我的 AppleTree 实例,而不是所有的 Tree 实例。看到了吗?

你会说:创建一个 AppleTreeImpl 接口并将属性放在那里......好吧..这将迫使接口地狱,只为一个属性创建......为我所有不同的树类型创建 Impl 接口?没有更短的解决方案吗?

当然,我看到了许多其他方法来实现整个东西,并解决动态引用类的需要,但是,如果我能通过这种方法特别地做到这一点,我很感兴趣。也无需过多使用接口或其他辅助类,也无需在 Tree 类之外使用公共属性。

【问题讨论】:

  • (如果有人建议反思,我会很生气。)
  • 嗯,反思是做他所描述的事情的唯一方法。做其他事情肯定是一个更好的主意。我建议使用Map<Class<? extends Tree>, Boolean>(实际上是一个集合)。
  • @Tom 哈哈,很有趣。在这种情况下还有什么建议?
  • @maaartinus 地图如何成为一个集合?
  • 这根本不是静态字段的用途。

标签: java class syntax static properties


【解决方案1】:

我建议把它放在课堂之外。在另一个班级GrowingRegistry,您可以在其中有一张地图 - Map<Class, Boolean>。所以你可以这样做:

GrowingRegistry.setAllGrown(AppleTree.class, true);

更好的是,您可以实现一个接口Tree,例如定义getTreeType(),并拥有映射Map<TreeType, Boolean>,其中TreeType 是一个枚举。所以:

GrowingRegistry.setAllGrown(TreeType.APPLE, true);

为了进一步扩展,您可以拥有 GardenProperties 对象,该对象包含“花园”的所有属性。

正如我提到的花园 - 整个问题来自您想要跟踪所有实例化对象的事实。是你实例化它们,不是吗?因此,您可以将所有实例放入您的集合中。例如:

Garden garden = new Garden();
garden.add(new AppleTreeImpl());
garden.add(new CherryTreeImpl());

在那里,您可以将实例存储在ListMap 中,还可以将花园用于所有属性的持有者。

【讨论】:

  • Skapi Bozho,我确实想出了几个类似的解决方案。但是我对他们不满意。它们在某种程度上并不优雅。看?我可能还有许多其他属性,例如 setAllGrown,而不仅仅是这一个。但是,也有解决方案。我的问题的答案现在包含在上面的评论中:“嗯,反思是做他所描述的事情的唯一方法。”由马丁努斯。也谢谢你的回答。
  • @PatlaDJ 我是否正确理解您想要层次结构中每个类(而不是每个实例)的一组属性?请注意,对于 OO 问题,反射应被视为最后的手段。我相信当涉及到 OO 问题时,很少需要反思。
  • “我是否正确理解您想要层次结构中每个类(而不是每个实例)的一组属性?” ---这正是我想要的。而且我希望它们也从公共外部类中引用,而不仅仅是它们的实例。在我刚刚了解到动态引用类的静态属性的唯一方法是通过 java.lang.reflection 之后,现在我计划按照您的建议通过外部注册表类来实现这个层次结构。
  • 我不想跟踪所有实例化的对象。我只是想不时为它们设置组属性,但正如我所说的,组必须从外部类动态引用。我已经完成了实现,猜猜我到底使用了什么'...属性'名称添加属性容器类:)
  • @PatlaDJ - 如果您不想自己跟踪它们,您可能正在犯设计错误。如果将来你需要有两个花园,JVM 将无法提供区分(两个静态组?:))
【解决方案2】:

如果你有一个对象,你可以直接做你在对象上提出的建议。

如果你有一个类,你可以使用反射:

try {
    treeClass.getField("areTheyAllGrown").set(treeClass, true);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
    // Do whatever you want with the error
    // e.g.: e.printStackTrace();
    // Or you could add a throws declaration
};

【讨论】:

    【解决方案3】:

    嗯,反思是做他所描述的事情的唯一方法。做其他事情肯定是一个更好的主意。我建议使用 Map,Boolean>(实际上是 Set)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 2015-05-20
      • 2013-07-12
      相关资源
      最近更新 更多