简体   繁体   English

如何实例化HashMap <K, V> ?

[英]How to instantiate a HashMap<K, V>?

First of all, I'm not an expert of generics, but I attempted to create a class to persist any type of object into a specified path using the following approach. 首先,我不是泛型专家,但是我尝试使用以下方法创建一个类以将任何类型的对象持久化到指定路径中。

 public class PersistentObject<T> {

  /**
   * Persisted object class.
   */
  private Class<T> clazz;
  /**
   * Persisted object.
   */
  private T object;
  /**
   * Path of the file where the object is persisted
   */
  private String path;

  public PersistentObject(String path, Class<T> clazz) {
    this.clazz = clazz;
    this.path = path;
    load(); //Load from file or instantiate new object
  }
}

It works fine, but I'm not able to use T as a class that implement the interface Map<K, V> , mainly because of the clazz constructor parameter. 它工作正常,但是我不能将T用作实现Map<K, V>接口的类,主要是因为clazz构造函数参数。 Here is what I'm trying to achieve: 这是我要实现的目标:

 PersistentObject<String> test =
      new PersistentObject<String>("path", String.class);

 PersistentObject<HashMap<String, Integer>> test2 =
      new PersistentObject<HashMap<String, Integer>>("path", HashMap<String, Integer>.class); // Compilation error

The problem is how can I pass a Class object that allows the instantiation of a HashMap<K, V> , eg HashMap<String, Integer> , if there is one? 问题是如何传递允许实例化HashMap<K, V>Class对象,例如HashMap<String, Integer> (如果存在)?

I guess there is a design flaw in my implementation, some misunderstanding of generics concepts, or both. 我猜我的实现中存在设计缺陷,对泛型概念的误解或两者兼而有之。 Any comments or suggestions are really welcome. 任何意见或建议都非常欢迎。

Thanks in advance. 提前致谢。

You are using a class literal to pass a Class object into your PersistentObject constructor. 您正在使用类文字来将Class对象传递到PersistentObject构造函数中。 However, generics aren't supported in class literals, because in Java generics is a compile-time feature. 但是,类文字中不支持泛型,因为在Java中,泛型是编译时功能。 Due to type erasure, the generic type parameters aren't available at runtime, presumably when you plan to use this Class object. 由于类型擦除,一般类型参数在运行时不可用,大概是在您计划使用此Class对象时。

Assuming that you need the Class object to instantiate a HashMap at runtime, the type information isn't available to create a HashMap<String, Integer> -- only a HashMap . 假设您需要Class对象在运行时实例化HashMap ,则类型信息不可用于创建HashMap<String, Integer> -仅可用于HashMap

To get it to compile, you can use an unchecked cast. 要使其编译,可以使用未经检查的强制转换。

PersistentObject<HashMap<String, Integer>> test2 =
    new PersistentObject<>("path",
        (Class<HashMap<String, Integer>>) (Class<?>) HashMap.class);

Casting to Class<?> from a class literal is allowed without a warning, but you'll get a compilation warning about casting that to a Class<HashMap<String, Integer>> . 允许在没有警告的情况下从类文字强制转换为Class<?> ,但是您将收到有关将其强制转换为Class<HashMap<String, Integer>>的编译警告。 You can use @SuppressWarnings("unchecked") to remove the warning. 您可以使用@SuppressWarnings("unchecked")删除警告。 Just be sure that this unchecked cast is indeed safe for your purposes. 只要确保此未经检查的演员表确实对您的目的是安全的。

import java.util.*;

public class PersistentObject<T> {

  /**
   * Persisted object class.
   */
  private Class<T> clazz;
  /**
   * Persisted object.
   */
  private T object;
  /**
   * Path of the file where the object is persisted
   */
  private String path;

  public PersistentObject(String path, Class<T> clazz) {
    this.clazz = clazz;
    this.path = path;
    //load(); //Load from file or instantiate new object
  }

  public static void main(String... args) {
    PersistentObject<String> test =
      new PersistentObject<String>("path", String.class);
    PersistentObject<HashMap<String, Integer>> test2 = new PersistentObject<>("path", (Class<HashMap<String, Integer>>) (Class<?>) HashMap.class);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM