java - 在类的构造函数中初始化泛型类型的数组,而无需传递 Class<T> 参数

标签 java generics

我有课:

class SomeClass<T extends SomeInterface>{

   private T[] myArray;

   public SomeClass()
   {
       // I want to initialize myArray in here to a default size of 100
       myArray = new T[100];  // this gives an error
   }

}

我知道我可以通过在构造函数中要求一个参数来解决这个问题:

class SomeClass<T extends SomeInterface>{

   private T[] myArray;

   public SomeClass(Class<T> clazz)
   {       
       myArray= (T[]) Array.newInstance(clazz, 100);
   }

}

但它使得没有场景必须传递两次通用参数。

换句话说,为了从类 SomeClass 中实例化一个对象,我将不得不做类似的事情:

SomeClass<SomeOtherClass> obj = 
      new SomeClass<SomeOtherClass>(SomeOtherClass.class);

我用c#编程,Java好像不太友好。我什至不明白为什么不能将 Object[] 数组转换为 SomeOtherClass[] 数组。在 c# 中这将是可能的...

所以我的问题是如何避免必须传递 SomeOtherClass.class 参数以便能够在类的构造函数中构造泛型数组...

最佳答案

虽然 Shakedown 列出了您问题的修复方法,但请允许我解释一下为什么创建泛型数组不是类型安全的。

我将通过 Effective Java 2nd Ed 中的示例来说明原因。

// Why generic array creation is illegal - won't compile! 
List<String>[] stringLists = new List<String>[1]; // (1) 
List<Integer> intList = Arrays.asList(42); // (2) 
Object[] objects = stringLists; // (3) 
objects[0] = intList; // (4) 
String s = stringLists[0].get(0); // (5)
  • Let’s pretend that line 1, which creates a generic array, is legal.

  • Line 2 creates and initializes a List<Integer> containing a single element.

  • Line 3 stores the List<String> array into an Object array variable, which is legal because arrays are covariant.

  • Line 4 stores the List<Integer> into the sole element of the Object array, which succeeds because generics are implemented by erasure: the runtime type of a List<Integer> instance is simply List, and the runtime type of a List<String>[] instance is List[], so this assignment doesn’t generate an ArrayStoreException. Now we’re in trouble. We’ve stored a List<Integer> instance into an array that is declared to hold only List<String> instances.

  • In line 5, we retrieve the sole element from the sole list in this array. The compiler automatically casts the retrieved element to String, but it’s an Integer, so we get a ClassCastException at runtime. In order to prevent this from happening, line 1 (which creates a generic array) generates a compile-time error.

关于java - 在类的构造函数中初始化泛型类型的数组,而无需传递 Class<T> 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8461544/

相关文章:

c# - 创建 Messenger 服务

java - 我如何让 Java 为我的类型安全映射文字推断出正确的通用映射类型?

java - Java 中的类型删除矛盾 : how does the compiled class file ensures type checking?

java - 为什么在泛型中需要 "? extends"

java - 程序找不到文件

java - Spring Boot 配置文件不选择属性文件

Java JApplet 渲染问题

android - 以编程方式向多人发送短信时出现一般错误

java - 有效的 Java Item42,至少一个输入参数

java - 使用 log4J-2.0-beta 时的 NPE