【问题标题】:Generic datatype Array creation where the type is inner class类型为内部类的通用数据类型数组创建
【发布时间】:2018-05-19 19:57:00
【问题描述】:

我有一个类 Table,它使用泛型类型 K 和 V 声明。它们用作内部类 Node 的参数的数据类型,我正在尝试为其创建实际的数组。 Table类的相关代码如下:

public class Table<K extends Comparable<K>, V> implements ITable<K,V> {
    private int numberOfElements;
    private boolean sorted;
    private Node[] list;

    //inner class
    private class Node{
        K key;
        V value;
        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }

    //constructor
    public Table(Class<Node> c){
        this.numberOfElements = 0;
        sorted = false;
        list = (Node[])Array.newInstance(c,1000);
        this.list = list;
    }

但是,在其他地方的实际代码中,我尝试使用具体数据类型(City 是我自己的具有 int 和 String 参数的类)调用 Table 的构造函数,如下所示:

 Table<Integer,City> table = new Table<Integer,City>(city.getClass());

我收到一个错误:Class&lt;CAP#1&gt; cannot be converted into class &lt;Table&lt;Integer,City&gt;.Node&gt; CAP#1 extends City from capture of ? extends City

我假设这与 Node 是 Table 的内部类有关,但 Table 类声明中不存在该问题的实际解决方案,因为我不知道如何处理通用数据类型数组。是的,它必须是一个数组,它写在练习描述中。

编辑:添加 City 类。这是一个只有两个参数的简单类。

public class City {
    public String name;
    public int ID;

    public City(String name, int iD) {
        this.name = name;
        this.ID = iD;
    }

    public String getName() {
        return name;
    }

    public int getiD() {
        return ID;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setiD(int iD) {
        this.ID = iD;
    }
}

我打算让节点基本上包含 City 的实例作为值和实例的 ID 作为键,以便轻松地将其拉出来进行搜索。我已经使用自定义数据结构进行了此练习,因此我知道该方法有效,但我无法正确声明通用数据类型数组

【问题讨论】:

  • 为什么你的public Table(Class&lt;Node&gt; c){参数是Class&lt;Node&gt; c?为什么要传递代表Class&lt;City&gt;city.getClass()?基于你调用像new Table&lt;Integer,City&gt;(city.getClass());这样的构造函数的事实,它不应该被声明为public Table(Class&lt;V&gt; c){吗?
  • 我不知道这是否能如我所愿。虽然节点中的 V 值确实包含 City 类实例,但我需要 K 键用于表中的搜索方法,我不知道如何从 V 值中提取 K。就我相当有限的知识(毕竟我还在做基本的学校练习)这是不可能的。我没有想到我为构造函数使用了错误的参数这一事实。或者更确切地说,确实如此,但我认为这是错误的,原因完全不同。

标签: java generics types


【解决方案1】:

你不需要使用Array.newInstance,因为组件类型是静态知道的,它是Node。在构造函数中,你不能这样做:

this.list = new Node[1000];

因为这隐式使用了Table&lt;K, V&gt;.Node,它是泛型的,你不能创建泛型数组。但是您可以使用以下命令将其强制为原始类型:

this.list = new Table.Node[1000];

然后从构造函数中删除Class&lt;Node&gt; 参数,您可以这样调用它:

Table<Integer, City> table = new Table<>();

从原始数组类型转换为通用数组类型时,您会收到未经检查的警告(如 cmets 中的 newacct 所解释的),您可以安全地禁止该警告。

【讨论】:

  • “使用原始类型作为数组组件类型时,您将收到未经检查的警告” 我认为从来没有使用原始类型作为数组组件类型的警告。相反,警告是针对涉及从 Table.Node[]Table&lt;K,V&gt;.Node[] 的未经检查的转换的分配
  • @newacct 啊,你是对的。试用int i = new Class[0].length; 不会发出警告。
猜你喜欢
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 2017-11-29
  • 1970-01-01
  • 2022-06-22
  • 2012-05-30
  • 1970-01-01
相关资源
最近更新 更多