Java 这种通用数组如何合法?

Java 这种通用数组如何合法?,java,generics,nested-generics,Java,Generics,Nested Generics,对我来说,泛型数组的问题(即它们的不可能性)似乎是一个反复出现的主题。下面是HashMap数据结构的相关代码。显然,我不能声明一个Bucket[],因为通用数组是不可能的。但是,我可以声明一个MapThing.Bucket[]。我断言这是一个好的实践,因为即使MapThing.Bucket[]是一个原始类型声明,但实际的MapThing.Bucket[]实例是由其封闭实例参数化的类型,对吗 谢谢你的洞察力 克里斯 公共类映射{ 私人桶[]; 公共静态void main(字符串[]argv){ M

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

谢谢你的洞察力

克里斯

公共类映射{
私人桶[];
公共静态void main(字符串[]argv){
MapThing thing=新的MapThing();
东西。放(“得到你的号码”,8675309);
}
@抑制警告(“未选中”)
公共地图{
Bucket=newMapThing.Bucket[314159];
}
公开作废认沽权(K键,V值){
铲斗=新铲斗(键、值);
//打印桶键类型:字符串,值:整数
System.out.println(“桶键类型:”
+bucket.getKey().getClass().getSimpleName()+“,值:”
+bucket.getValue().getClass().getSimpleName());
bucket[Math.abs(key.hashCode()%bucket.length)]=bucket;
}
私有类桶{
私钥;
私人价值;
铲斗(K键,V值){
this.key=key;
这个值=值;
}
公共K getKey(){
返回键;
}
public V getValue(){
返回值;
}
}
}
显然,我不能声明Bucket[],因为泛型数组是 不可能

  • 您始终可以声明任何数组类型的变量。总是。声明
    Bucket[]
    ArrayList[]
    或其他变量是非常好的

  • 不能将数组创建表达式(即
    new X[…]
    )与参数化类型一起使用(即如果
    X
    Something
    ,其中
    SomethingElse
    之外的任何东西?
    )。可以将数组创建表达式与原始类型一起使用(即
    new X[…]
    其中
    X
    是原始类型),例如
    new ArrayList[10]

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

    要获取原始类型,需要使用外部类显式限定它,如
    mapshing.Bucket
    中所示。所以
    新的MapThing.Bucket[10]
    将起作用

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


  • 你当然可以声明一个
    Bucket
    数组,为什么你认为你不能呢?您使用的是原始类型,不应该这样做。实际数组对泛型一无所知。不,我不能声明一个Bucket数组:Bucket[]Bucket=new Bucket[12];//给出以下错误:“无法创建MapThing.Bucket的通用数组”尝试将
    Bucket
    声明为
    私有类Bucket{
    ,然后可以使用类似
    私有Bucket Bucket[];
    Bucket=new Bucket[10];
    …啊。
    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;
        }
      }
    }