Java 可选参数未按预期工作
Java optional parameter not working as expected
我目前正在运行 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 (尺寸 2)。如果我传递 new Character[]{'a','b'} 而不是 currentKeySequence,它会按预期工作,而无需将数组放入包装器数组。
更新:
换句话说,我有 currentKeySequence = test = Character[]{'a','b'} 其中唯一的区别是 currentKeySequence 是从列表中检索的,而 var 测试是在本地实例化的 "new"关键字。
如果我通过了 var 测试,那么 keySequence=Character[]{'a','b'} 如果我通过了 currentKeySequence,那么 keySequence=Object[]{Character[]{'a','b'}}。我知道如果我调用 get('a','b'),keySequence 将是一个 Object[]{'a','b'}。我希望如果参数总是包装到一个数组中,两种情况都是一样的。
我是做错了什么还是这是一个错误?
这不是错误。这就是 varags 的工作原理。
可变参数 (varags) 允许您不传入参数或传入多个参数。为此,它使用一个数组来跟踪参数。单个参数并不特殊;它存储在数组的第一个索引中。
在执行任何操作之前检查数组是否包含项目总是好的,因为客户端可以不为参数指定参数。
你的可变参数结构正在按照它的指示行事。它将您提供的所有内容封装到某种类型的数组中 K
.
如果你传递一个数组数组;也就是说,如果您传入可以扩展为二维数组的内容,那么可变参数会将其解释为可变参数数组的单个参数。
在您的问题中,这也将被视为二维数组:
new Object[]{new Character[]{'a','b'}}
原因:它是 Character[]
嵌套在 Object[]
中(完全合法)。
问题出在线路上
private K currentKeySequence = null;
K 是 Character,但 var currentKeySequence 被分配给 Character[] (K[])。在调试器中没有出现任何问题,也没有在运行时出现问题,但是当变量作为参数传递时,它作为 Object[]{Character[]{...}} 到达方法。在 currentKeySequence 定义中将 K 更改为 K[] 后,该方法接收到正确的参数(只是 Character[]{...});
我目前正在运行 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 (尺寸 2)。如果我传递 new Character[]{'a','b'} 而不是 currentKeySequence,它会按预期工作,而无需将数组放入包装器数组。
更新: 换句话说,我有 currentKeySequence = test = Character[]{'a','b'} 其中唯一的区别是 currentKeySequence 是从列表中检索的,而 var 测试是在本地实例化的 "new"关键字。
如果我通过了 var 测试,那么 keySequence=Character[]{'a','b'} 如果我通过了 currentKeySequence,那么 keySequence=Object[]{Character[]{'a','b'}}。我知道如果我调用 get('a','b'),keySequence 将是一个 Object[]{'a','b'}。我希望如果参数总是包装到一个数组中,两种情况都是一样的。
我是做错了什么还是这是一个错误?
这不是错误。这就是 varags 的工作原理。
可变参数 (varags) 允许您不传入参数或传入多个参数。为此,它使用一个数组来跟踪参数。单个参数并不特殊;它存储在数组的第一个索引中。
在执行任何操作之前检查数组是否包含项目总是好的,因为客户端可以不为参数指定参数。
你的可变参数结构正在按照它的指示行事。它将您提供的所有内容封装到某种类型的数组中 K
.
如果你传递一个数组数组;也就是说,如果您传入可以扩展为二维数组的内容,那么可变参数会将其解释为可变参数数组的单个参数。
在您的问题中,这也将被视为二维数组:
new Object[]{new Character[]{'a','b'}}
原因:它是 Character[]
嵌套在 Object[]
中(完全合法)。
问题出在线路上
private K currentKeySequence = null;
K 是 Character,但 var currentKeySequence 被分配给 Character[] (K[])。在调试器中没有出现任何问题,也没有在运行时出现问题,但是当变量作为参数传递时,它作为 Object[]{Character[]{...}} 到达方法。在 currentKeySequence 定义中将 K 更改为 K[] 后,该方法接收到正确的参数(只是 Character[]{...});