【问题标题】:Error: Generic Array Creation [duplicate]错误:通用数组创建 [重复]
【发布时间】:2022-01-17 01:09:16
【问题描述】:

我不明白 Generic Array Creation 的错误。
首先我尝试了以下方法:

  public PCB[] getAll() {
       PCB[] res = new PCB[list.size()];
           for (int i = 0; i < res.length; i++) {
               res[i] = list.get(i);
            }
       list.clear();
       return res;
}


然后我尝试这样做:

PCB[] res = new PCB[100];


我一定错过了一些看起来正确的事情。我试着查了一下,我真的做到了。什么都没有点击。


我的问题是:我能做些什么来解决这个问题?


错误是:

.\Queue.java:26: generic array creation
PCB[] res = new PCB[200];
            ^
Note: U:\Senior Year\CS451- file      
uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

工具已完成,退出代码为 1

【问题讨论】:

  • 你能发布异常/错误
  • 我假设 PCB 是一个泛型类型参数,因此,由于类型擦除,您在 Java 中所做的事情是不可能的。如果这一切都是真的,您应该点击我标记为重复的链接,因为它提供了一种解决方法。
  • 已经尝试阅读该帖子。它对我没有帮助
  • 可悲的事实是,Java 有意识地决定明确阻止这种语法工作。 Java 实现了类型擦除,这意味着类型参数PCB 在运行时实际上没有任何意义(或者从技术上讲,它确实如此,但它可能只是Object 这对你没有任何好处)。有两种方法可以规避此限制。两者都在我引用的链接中进行了详细解释。让我知道您在该解决方案的哪个特定部分遇到问题。
  • PCB>[] res = new PCB>[100];是可能的

标签: java arrays generics class object


【解决方案1】:

您不能创建具有通用组件类型的数组。

改为创建一个显式类型的数组,例如Object[]。然后,您可以根据需要将其转换为 PCB[],但在大多数情况下我不建议这样做。

PCB[] res = (PCB[]) new Object[list.size()]; /* Not type-safe. */

如果您想要类型安全,请使用 java.util.List&lt;PCB&gt; 之类的集合而不是数组。

顺便说一句,如果list 已经是java.util.List,您应该使用它的toArray() 方法之一,而不是在您的代码中复制它们。不过,这并不能解决类型安全问题。

【讨论】:

  • 是的,但是当您将其返回到外部时,调用者会将其分配给 PCB[] 类型的变量。繁荣你会得到一个类转换异常
  • @newacct - 这不一定会发生。这取决于调用上下文。但它可能发生。这就是我所说的“非类型安全”的意思,也是我反对它的原因。
  • @erickson:随着递归的展开,它最终会在某个时刻发生。泛型总是在某个时候变得具体,否则将无法完成任何工作。这合理工作的唯一方法是,如果结果从未实际用作PCB 的实际类型的数组。在这种情况下,最好将自己声明为返回 Object[]
  • @erickson:没错,既然是这样,那么只需返回一个Object[],因为它是类型安全的,并且根本不会限制使用。除了Object[] 之外的任何使用结果基本上都会引发运行时错误,那么你为什么还要费心返回其他任何东西呢?
  • @erickson,实际上,我发现了一个不完全愚蠢的用法示例。如果泛型数组仍然封装在一个集合(例如 ArrayList)中,那么对数组的访问和从该数组的访问是通过泛型单独执行的,并且它可以工作。没有考虑将其作为实例变量保留。
【解决方案2】:

以下将为您提供所需类型的数组,同时保持类型安全。

PCB[] getAll(Class<PCB[]> arrayType) {  
    PCB[] res = arrayType.cast(java.lang.reflect.Array.newInstance(arrayType.getComponentType(), list.size()));  
    for (int i = 0; i < res.length; i++)  {  
        res[i] = list.get(i);  
    }  
    list.clear();  
    return res;  
}

my answer 对 Kirk Woll 链接为副本的问题进行了深入解释。

【讨论】:

    【解决方案3】:

    除了“可能重复”中建议的方法之外,解决此问题的另一个主要方法是由调用者提供数组本身(或至少一个模板),他们希望知道具体的类型,因此可以安全地创建数组。

    这就是像ArrayList.toArray(T[]) 这样的方法的实现方式。我建议你看看那个方法以获得灵感。更好的是,正如其他人所指出的那样,无论如何您都应该使用该方法。

    【讨论】:

      猜你喜欢
      • 2016-01-01
      • 2018-03-14
      • 2011-10-31
      • 2011-04-23
      相关资源
      最近更新 更多