【问题标题】:How do I set the type of reference for the list?如何设置列表的引用类型?
【发布时间】:2017-11-11 17:28:25
【问题描述】:

我是 Java 新手。我需要定义一个构造函数MyArrayList(Object type) 来设置稍后添加到列表中的引用类型。

构造函数的签名不能更改。此外,我不允许使用泛型

我尝试这样做:

public class MyArrayList implements MyList {
private Object[] theList; // array of objects


public MyArrayList(Object type) {
    theList = new type[0];

}

并得到一个编译错误,因为type 不是类。这样做的正确方法是什么?

【问题讨论】:

  • 使用泛型并完全抛弃构造函数。
  • “并得到一个编译错误” - 总是把你得到的完整错误发给我们。否则,您的受众就会缩小到立即知道问题所在的人。
  • @abovady 如果用户回答了您的问题,请同时接受他的回答 (Accepting Answers: How does it work?)。如果没有,请说明哪些问题仍未得到答复,这是 StackOverflow 的关键部分,非常感谢。

标签: java types casting


【解决方案1】:

正如您所说,您不想使用泛型,您可以通过Array#newInstance (documentation) 动态创建数组。这是您调整后的代码:

public class MyArrayList implements MyList {
    private Object[] theList;

    public MyArrayList(Object type) {
        // Adjust as you like
        int size = 0;
        // Dynamically create array of type "type"
        theList = (Object[]) Array.newInstance(type.getClass(), size);
    }
}

由于您在编译时不知道该类,您只能将其用作Object[],但是它只允许在运行时使用type 的真实类型的元素,一旦类型已知,而不是任意的@987654326 @s.


请注意,数组固定大小。您不能只向它们添加元素,大小始终是固定的,并且必须提前知道。如果您需要更动态的结构,请使用List(例如ArrayListLinkedList)。

然后您可以只记住给定的type 对象,如果用户尝试添加您检查element instanceof type 的项目,并且仅在返回true 时添加,否则抛出类似IllegalArgumentException 左右的异常。

或者,如上所述,为您的数组设置一个好的固定大小。您还可以通过在构造函数中提供 size 参数来为用户提供选择。

【讨论】:

  • 谢谢,我尝试实现您的解决方案,但是当我动态创建数组时出现编译器错误“类型不匹配”。 'newInstance' 返回一个对象,'theList' 是 Object[]。
  • @abovady 我已经编辑了代码并向Object[] 添加了强制转换,因为该方法返回Object 而不是数组(但真正的类型实际上是数组)。你能再试一次吗?
  • 谢谢,它成功了。我的数组的大小是灵活的。如果添加的元素超出边界,我将元素添加到数组的末尾。我通过创建一个长度为 +1 的新数组并将旧数组的内容复制到一个新数组来做到这一点。
  • @abovady 是的,这行得通,但效率低下。 ListArrayListLinkedList 这样的实现更聪明,add 在(平均)恒定时间内工作,而您的方法总是需要线性时间。
【解决方案2】:

Java 中这种情况的答案是“泛型”。 java 官方documentation 是学习泛型的好地方。

对于这种情况,您可以编写如下代码

列表界面

package test.generics;

public interface MyList<T> {
    T get(int index);
    void add(T input);
    void clear();
}

实现

package test.generics;

public class MyArrayList<T> implements MyList<T> {

    private Object[] storage = new Object[10];
    private int index = 0;

    @SuppressWarnings("unchecked")
    @Override
    public T get(int index) {
        T temp = null;
        if (!(index < 10 && index >= 0)) {
            throw new IllegalArgumentException("Expected range 0 to 9");
        } else {
            temp = (T) storage[index];
        }
        return temp;
    }

    @Override
    public void add(T input) {
        if (index < 10) {
            storage[index++] = input;
        } else {
            throw new IllegalArgumentException("Only 10 items supported");
        }
    }

    @Override
    public void clear() {
        index = 0;
    }

}

消费者

package test.generics;

public class Consumer {

    public static void main(String[] args) {
        MyList<Integer> intList = new MyArrayList<>();
        intList.add(10);
        System.out.println(intList.get(0));
        MyList<String> stringList = new MyArrayList<>();
        stringList.add("hello");
        System.out.println(stringList.get(0));
    }

}

【讨论】:

  • 我了解您的解决方案,但我不允许使用类型参数。我必须使用带有我描述的签名的构造函数。
猜你喜欢
  • 1970-01-01
  • 2011-01-31
  • 2016-11-10
  • 2015-01-28
  • 2012-04-09
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
相关资源
最近更新 更多