2

我有这个代码:

import java.util.*;
import java.lang.*;
import java.io.*;

class Main{
    public static void main (String[] args){
        Foo<String> foo = new Foo<String>(1000);
    }
}

class Foo<Key extends Comparable<Key>>{
    private Entry[] a;
    private class Entry{
        Key key;
    }
    public Foo(int size){
        a = (Entry[])new Object[size]; // <- this is the problem
    }
}

当我编译它时,我得到一个错误,说:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LFoo$Entry;
at Foo.<init>(Main.java:17)
at Main.main(Main.java:7)

我试过:

import java.util.*;
import java.lang.*;
import java.io.*;

class Main{
    public static void main (String[] args){
        Foo<String> foo = new Foo<String>(1000);
    }
}

class Foo<Key extends Comparable<Key>>{
    private Entry[] a;
    private class Entry{
        Key key;
    }
    public Foo(int size){
        a = new Entry[size];
    }
}

但后来我收到一条错误消息:

Main.java:17: error: generic array creation
        a = new Entry[size];
            ^

是否可以创建该数组?

4

4 回答 4

1

这是因为泛型不能很好地处理数组(在编译时)。

您应该使用一些集合,而不是:

class Foo<Key extends Comparable<Key>> {
    private List<Entry> a;

    private class Entry {
        Key key;
    }

    public Foo(int size) {
        a = new ArrayList<Entry>(size);
    }
}
于 2015-07-29T13:55:35.487 回答
1

好吧,实际上你可以通过reflection

public class Main {
    public static void main(String[] args) {
        Foo<String> foo = new Foo<String>(1000);
        foo.a[0] = foo.new Entry();
        foo.a[0].key = "ss";
    }
}

class Foo<Key extends Comparable<Key>> {
    public Entry[] a;

    public class Entry {
        Key key;
    }

    public Foo(int size) {
        a = (Entry[]) java.lang.reflect.Array.newInstance(Entry.class, size);
    }
}
于 2015-07-29T13:58:54.693 回答
1

我同意 kocko 的观点,即您应该使用一些Collection而不是数组。但具体到您的观点,它为我编译并运行。这只是将创建数组的责任推给了Array.newInstance方法。缺点是它强迫演员

 class Foo<Key extends Comparable<Key>>{
     private Entry[] a;
     private class Entry{
       Key key;
     }
     public Foo(int size){
       a = (Entry[])Array.newInstance(Entry.class,size);
     }
}
于 2015-07-29T14:00:37.087 回答
0

作为一个内部类,该类型在封闭类中声明Entry的类型参数的范围内。Key换句话说,Entry也是通用的。

您可以使用

a = (Entry[]) new Foo<?>.Entry[size];

或原始等价物(我不推荐)

a = (Entry[]) new Foo.Entry[size];

JLS 中解释了这种类型的数组创建

ArrayCreationExpression:
    new ClassOrInterfaceType DimExprs [Dims]

陈述

如果ClassOrInterfaceType 不表示可具体化类型第 4.7 节),则为编译时错误。

可具体化类型在哪里

当且仅当满足以下条件之一时,类型才是可具体化的:

  • 它指的是非泛型类或接口类型声明。
  • 它是一种参数化类型,其中所有类型参数都是无界通配符(第 4.5.1 节)。
  • 它是原始类型(§4.8)。
  • 它是一种原始类型(§4.2)。
  • 它是一个数组类型(第 10.1 节),其元素类型是可具体化的。
  • T它是一种嵌套类型,其中,对于以“.”分隔的每种类型,T其本身都是可具体化的。

通过使用通配符或原始类型的参数化,我们可以获得上面呈现的数组创建表达式。

于 2015-07-29T15:20:54.177 回答