Java 映射,键 = 类,值 = 该类的实例

2022-09-01 17:16:57

我不确定我想做什么是可能的,但如果是,我想找出方法。基本上,我想创建一个 Map,其中键是一个类 (),该条目的值是该类的实例。目前我有java.lang.Class

private Map<Class<?>, Object> myMap = new HashMap<Class<?>, Object>();

但是,这意味着任何对象都可以放置在地图中。如果可能的话,我想让它,所以只有键中的类的实例可以放在映射中。有没有办法使用 ?类上的参数化以确保这一点?

另外,我发现在执行此类操作时可能存在内存泄漏。我不确定我是否完全理解这是如何发生的。我只会将单例对象粘贴到映射中,因此是否仍会担心内存泄漏?如果是这样,我该如何防止?


答案 1

Java的类型系统根本不够强大,无法直接强制执行您描述的类型约束,并且您需要执行一些不安全的强制转换才能使这项工作 - 或者将它包装在强制执行类型安全性的其他API中。Guava的ClassToInstanceMap正是为这个用例做到这一点的,它提供了一个外部安全的API,对接口施加了额外的限制,使其正常工作。(披露:我为番石榴做出贡献。MapMap

这可能导致内存泄漏的唯一情况是,如果您在此处使用的某些类在应用程序的生命周期内不会保留。对于许多用户来说,这不是一个问题,特别是如果您正在编写一个“服务器端”应用程序,该应用程序并不关心卸载未使用的类。


答案 2

您使用的是一个异构容器。这些可以通过使用类型标记(就像您已经做的那样)和使用正确的应用程序逻辑来使这些内容成为类型安全的:因此,其中存在一个未经检查的抑制警告,但应用程序逻辑保证了正确性。Class.cast()Class.cast()

我建议你阅读Josh Bloch的《Effective Java Item 29:考虑类型安全的异构容器》。他的例子是:

// Typesafe heterogeneous container pattern - implementation
public class Favorites {
  private Map<Class<?>, Object> favorites =
    new HashMap<Class<?>, Object>();

  public <T> void putFavorite(Class<T> type, T instance) {
    if (type == null)
      throw new NullPointerException("Type is null");
    favorites.put(type, instance);
  }

  public <T> T getFavorite(Class<T> type) {
    return type.cast(favorites.get(type));
  }
}

我只看到内存泄漏的可能性,如果你持有任意许多不同类型的你实际上不再需要。


推荐