这个通用数组如何合法?

时间:2014-11-17 00:20:07

标签: java generics nested-generics

通用数组的问题(即它们的不可能性)对我来说似乎是一个反复出现的主题。下面是HashMap数据结构的相关代码。显然,我不能声明Bucket[],因为通用数组是不可能的。但是,我可以声明MapThing.Bucket[]。当我断言这是一个好习惯时,我是否正确,因为即使MapThing.Bucket[]是原始类型声明,实际的MapThing.Bucket[]实例是由其封闭实例参数化的类型?

感谢任何见解!!!

克里斯

public class MapThing<K, V> {
  private Bucket buckets[];

  public static void main(String[] argv) {
    MapThing<String, Integer> thing = new MapThing<>();
    thing.put("got your number", 8675309);
  }

  @SuppressWarnings("unchecked")
  public MapThing() {
    buckets = new MapThing.Bucket[314159];
  }

  public void put(K key, V value) {
    Bucket bucket = new Bucket(key, value);

    // Prints typeof bucket key: String, value: Integer
    System.out.println("typeof bucket key: "
    + bucket.getKey().getClass().getSimpleName() + ", value: "
    + bucket.getValue().getClass().getSimpleName());

    buckets[Math.abs(key.hashCode() % buckets.length)] = bucket;
  }

  private class Bucket {
    private K key;
    private V value;

    Bucket(K key, V value) {
      this.key = key;
      this.value = value;
    }

    public K getKey() {
      return key;
    }

    public V getValue() {
      return value;
    }
  }
}

1 个答案:

答案 0 :(得分:1)

  

显然,我不能声明Bucket [],因为通用数组是   不可能的。

  1. 您可以声明任何数组类型的变量。总是。声明Bucket[]ArrayList<String>[]或其他任何变量是完全正常的。

  2. 您不能将数组创建表达式(即new X[...])与参数化类型一起使用(即如果XSomething<SomethingElse>,其中SomethingElse?之外的任何内容1}})。您可以使用具有原始类型的数组创建表达式(即new X[...],其中X是原始类型),例如new ArrayList[10]

    因此,如果Bucket是原始类型,那么new Bucket[10]就可以了。问题是,Bucket不是原始类型。 Bucket是泛型外部类中的非静态内部类。这意味着它在其外部类的类型参数的范围内。换句话说,如果您在Bucket内编写非限定类型MapThing,则隐含地表示MapThing<K,V>.Bucket,这是参数化类型。

    要获取原始类型,您需要使用外部类明确限定它,如MapThing.Bucket中所示。所以new MapThing.Bucket[10]会有用。

    或者,如果您不想使用原始类型,可以使用所有通配符对其进行参数化:new MapThing<?,?>.Bucket[10]