我正在尝试编写一个以 List 对象作为输出参数的 Java 函数。
boolean myFunction(int x, in y, List myList)
{
/* ...Do things... */
myList=anotherList.subList(fromIndex, toIndex);
return true;
}
在调用该函数之前,我声明 myList 如下:
List myList=null;
然后我调用该函数
myFunction(x,y,myList)
但是当我尝试操作myList时,我发现myList仍然为空。
我确信我的函数代码中的变量
anotherList
不为空,并且我确信subList
函数返回一个非空列表。
原因是什么?如何在 Java 函数中传递 List 作为输出参数?
Java 总是使用按值传递。这意味着操作传递的变量不会影响调用者传递的变量。
为了解决您的问题,有一些可能性:
返回子列表:
List myFunction(int x, int y) { return anotherList.subList(....);}
我知道这种方式可以消除你的布尔返回值。
创建一个结构体来保存指向列表的指针。
class Reference <T>
{
public T ref;
}
boolean myFunction(int x, int y, Reference<List> listRef)
{
listRef.ref = anotherList.subList(....);
return true;
}
创建一个结构来保存您希望该方法返回的所有输出:
class MyFunctionOutput
{
List list;
boolean b;
}
MyFunctionOutput myFunction(int x, int y)
{
MyFunctionOutput out = new MyFunctionOutput();
out.list = anotherList.subList(....);
out.b = true;
return out;
}
或者最简单的方法:传递一个初始化的 List 而不是 null 并让函数添加子列表,就像 Attila 建议的那样。
您无法在 Java 中传递 out 参数。您需要将返回类型声明为列表或更改传递列表的contents:
boolean myFunction(int x, in y, List myList)
{
...Do things...
myList.clear();
myList.addAll(anotherList.subList(fromIndex, toIndex));
return true
}
注意:输出参数意味着您更改包含传递给函数的值的变量的值。在你的情况下,这意味着返回一个不同的 List 对象。相反,您将返回相同列表对象,但内容已更改。
将参数视为传递值的本地副本:替换整个对象的任何更改都将在函数返回时丢失。如果您只是更改其内容/状态,则当您访问传入的同一对象时,该更改将保留(本地副本由指向同一对象的引用组成)
注意:它可能是出于演示目的,但您应该使用泛型来指定列表包含的对象:例如
List<String>
而不是原始 List
类型
引用是按值传递的。所以你不能指定 out 参数。
但是,您可以做的是改变传入的对象。因此,在上面的示例中,您可以传入一个空的
List
,并将其填充到您调用的方法中。
即上面:
myList.addAll(...);
您可能希望断言传递的列表为空作为先决条件。
我也许会认为这在 Java 世界中并不是一种很常见的模式。因为 out 参数 不存在,所以作为参数传入的参数会改变并不是预期的行为,并且您最好创建一个合适的对象类型来返回。
myList 变量是该函数的本地变量。在 Java 世界中,引用是按值传递的,而不是按指针传递的。一旦退出,它就会从上下文堆栈中删除。一个可能的选择是不返回布尔值,而是返回列表本身。然后你可以测试列表是否为空,看看你的函数是否有效。
另一种选择是实际创建列表,然后将其传递给函数(非空)。那么你的函数不需要创建一个新列表,而只需向其中添加值即可。
一个简短的答案 - 只需返回新列表作为函数的返回值:
List myFunction(int x, in y, List myList) {
...Do things...
return anotherList.subList(fromIndex, toIndex);
}
长的答案是,当您调用函数时,java会复制对象的指针,这意味着如果您将新对象分配给方法参数,它不会影响原始变量。所以如果你想改变对象值,你必须保存参数引用。