传递参数与从函数返回参数
从标题中可以清楚地看出我们应该采用哪种方法?
意图是传递一些方法参数并获得输出。 我们可以传递另一个参数,方法会更新它,方法现在不需要返回任何东西,方法只会更新输出变量,它会反映给调用者。
我只想通过这个例子来构建问题。
List result = new ArrayList(); for (int i = 0; i < SOME_NUMBER_N; i++) { fun(SOME_COLLECTION.get(i), result); } // in some other class public void fun(String s, List result) { // populates result }
与
List result = new ArrayList(); for (int i = 0; i < SOME_NUMBER_N; i++) { List subResult = fun(SOME_COLLECTION.get(i)); // merges subResult into result mergeLists(result, subResult); } // in some other class public List fun(String s) { List res = new ArrayList(); // some processing to populate res return res; }
我明白一个人通过了参考而另一个没有。
我们应该选择哪一种(在不同情况下)以及为什么?
更新 :仅考虑可变对象。
从函数返回值通常是编写代码的更简洁的方法。 由于创建和销毁指针的性质,传递值并修改它是更多的C / C ++风格。
开发人员通常不希望通过传递函数来修改它们的值,除非函数明确声明它修改了值(我们经常浏览文档)。
但也有例外。
考虑一下Collections.sort
的例子,它实际上确实做了一个列表的排序。 想象一下包含100万件物品的清单,你正在对它进行分类。 也许你不想创建另外有100万条目的第二个列表(即使这些条目指向原始条目)。
支持使用不可变对象也是一种好习惯。 不可变对象在开发的大多数方面(例如线程)引起的问题要少得多。 因此,通过返回一个新对象,您不会强制参数变为可变。
重要的是要明确你在方法中的意图。 我的建议是尽可能避免修改参数,因为它不是Java中最典型的行为。
你应该归还它。 你提供的第二个例子是要走的路。
首先,它更清楚。 当其他人阅读您的代码时,他们可能没有注意到参数被修改为输出。 您可以尝试命名变量,但是当涉及到代码可读性时,它更可取。
你应该返回而不是传递它的大原因是使用不可变对象。 你的例子,List,是可变的,所以它可以正常工作。 但是如果你试图以这种方式使用String, 它将无法工作。
由于字符串是不可变的,如果你将一个字符串作为参数传递,然后该函数说:
public void fun(String result){ result = "new string"; }
您传入的结果值不会被更改。 相反,本地范围变量’result’现在指向一个有趣的新字符串,但您的调用方法中的结果仍然指向原始字符串。
如果你打电话:
String test = "test"; fun(test); System.out.println(test);
它将打印:“测试”,而不是“新字符串”!
所以肯定,它优于回归。 🙂
返回它将使代码更清晰,并减少方法/类之间的耦合。
这更多是关于最佳实践和您自己的编程方法。 我会说如果你知道这将是一个值返回类型函数,如:
函数IsThisNumberAPrimeNumber {}
然后你知道这只会返回一个布尔值。 我通常使用函数作为帮助程序而不是大的子程序。 我还应用命名约定来帮助指示我期望sub \ function将返回的内容。 例子:
GetUserDetailsRecords GetUsersEmailAddress IsEmailRegistered
如果你看看这3个名字,你可以告诉第一个是给你一些列表或类的多个用户详细记录,第二个会给你一个电子邮件的字符串值,第三个可能会给你一个布尔值。 如果你改变了名字,你改变了意思,所以我想再考虑这个。
我认为我们不理解的原因是这两种行为完全不同。 将变量传递给函数是一种提供函数数据的方法。 从函数返回它是一种将数据传递出函数的方法。
如果你的意思是这两个动作之间的区别:
public void doStuff(int change) { change = change * 2; }
和
public void doStuff() { int change = changeStorage.acquireChange(); change = change * 2; }
然后第二个通常更干净,但有几个原因(安全性,function可见性等)可以阻止您以这种方式传递数据。
它也是首选,因为它使重用代码更容易,并使其更加模块化。