Java可选参数无法按预期工作

时间:2015-01-05 21:57:10

标签: java generics optional-parameters

我目前正在运行java 7,我发现java在特定情况下有一种奇怪的行为。下面的代码显示了通用Trie数据结构的迭代器的next():

public final Iterator iterator = new Iterator()
{
    private int objsProcessed = 0;
    private K currentKeySequence = null;

    @Override
    public boolean hasNext()
    {
        return objsProcessed < numObjects;
    }

    @Override
    public Object next()
    {
        if (keySequences.isEmpty() == false)
        {
            currentKeySequence = keySequences.get(objsProcessed);
        }
        else
        {
            return null;
        }
        objsProcessed++;
        Character[] test=new Character[]{'a','b'};
        Object result = reference.get(test);
        result = reference.get(currentKeySequence);
        return result;
    }

    @Override
    public void remove()
    {
        reference.remove(currentKeySequence);
    }
};

以下添加了键序列:

public Trie add(V object, K... keySequence)
{
    Node<K, V> currentNode = root;
    for (int i = 0; i < keySequence.length; i++)
    {
        currentNode = currentNode.insert(new Node<K, V>(keySequence[i],
                currentNode));
    }
    currentNode.addObject(object);
    keySequences.add((K) keySequence);
    numObjects++;
    return this;
}

get方法采用可变数量的参数:

public List<V> get(K... keySequence)
{
    Node<K, V> currentNode = root;
    for (int i = 0; i < keySequence.length; i++)
    {
        currentNode = currentNode.getNode(keySequence[i]);
    }
    if (currentNode != null)
        return currentNode.getObjects();
    else
        return null;
}

问题在于,当我传递currentKeySequence时,在我的测试用例中,是一个大小为2的Character [],它使keySequence变量实际上是一个大小为1的数组,它包含currentKeySequence而不仅仅是currentKeySequence(size 2)。如果不是currentKeySequence,我传递新的Character [] {'a','b'}它按预期工作,而不将数组放在包装器数组中。

更新 换句话说,我有currentKeySequence = test = Character [] {'a','b'},唯一的区别是从列表中检索currentKeySequence,并使用“new”关键字在本地实例化var测试。

如果我通过var测试,那么keySequence = Character [] {'a','b'}如果我传递currentKeySequence,则keySequence = Object [] {Character [] {'a','b'} }。我知道如果我调用get('a','b'),keySequence将是一个Object [] {'a','b'}。我希望如果参数总是包装成一个数组,两种情况都是一样的。

我做错了什么或者这是一个错误?

3 个答案:

答案 0 :(得分:3)

这不是一个错误。这就是varags的工作原理。

变量参数(varags)允许您传入无参数或多个参数。为此,它使用数组来跟踪参数。一个论点并不特别;它存储在数组的第一个索引中。

在执行任何操作之前检查数组是否包含项总是很好的,因为客户端可以为参数指定无参数。

答案 1 :(得分:2)

你的varargs结构正在按照它所说的去做。它将您提供的所有内容封装到某种类型K的数组中。

如果传递数组数组;也就是说,如果传入可以扩展为二维数组的东西,那么varargs会将其解释为varargs数组的单个参数。

在你的问题中,这也被认为是一个二维数组:

new Object[]{new Character[]{'a','b'}}

原因是:它Character[]嵌套在Object[]内(完全合法)。

答案 2 :(得分:0)

问题在于这条线 private K currentKeySequence = null;

K是Character但是var currentKeySequence被分配给Character [](K [])。调试器中没有出现任何问题或在运行时引发问题,但当变量作为参数传递时,它作为Object [] {Character [] {...}}到达方法。一旦K在currentKeySequence定义中更改为K [],该方法就会收到正确的参数(只有Character [] {...});