[英]Is it a bad practice to use arrays as parameter(s) to return multiple values
我有时(实际上,经常)发现自己使用单元素数组从方法返回多个值。 像这样的东西:
public static int foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
param2[0] = <some value>;
param3[0] = <some value>;
return <some value>;
}
这是一种不好的做法吗? (好像是因为我的一些朋友说他们不知道它在做什么2秒!)但我之所以这么做的原因是因为这看起来最接近所谓的pass-by-reference
C ++中的pass-by-reference
。 在C++
并没有劝阻这种做法,所以......
但如果这真的是一种错误的做事方式,那么任何想法如何以干净的方式重写它?
谢谢
创建一个包含要返回的数据的对象。
然后,您可以返回该对象的实例。
class FooData {
private int someInt;
private int anotherInt;
private String someString;
public FooData(int a, int b, String c) {
someInt = a;
anotherInt = b;
someString = c;
}
}
public FooData foo() {
// do stuff
FooData fd = new FooData(blah, blahh, blahhh);
return fd;
}
虽然我同意这里的一般意见,为此目的使用数组是不好的做法,但我想补充一些内容。 您确定首先通过“参考传递”确实是您所需要的吗? 很多人说你的代码风格不好,但现在让我告诉你为什么那是恕我直言。 “通过引用传递”主要是“通过副作用编程”的同义词,这是你总是想要避免的事情。 它使代码更难以调试和理解,并且在多线程环境中,这种态度的不良影响确实会给你带来困难。 要在Java中编写可伸缩且线程安全的代码,您应该尽可能地使对象“只读”,即理想情况下,您创建一个对象并同时对其进行初始化,然后在整个应用程序中使用此不可修改的状态。 对状态的逻辑更改几乎总是被视为新状态的“创建”,即创建初始化为当时所需状态的新实例。 许多现代脚本语言只允许您以这种方式工作,它使事情更容易理解。 与C ++相反,Java在分配和释放短期对象方面效率更高,因此其他人建议的内容实际上没有任何问题:创建一个特殊类的实例来保存函数结果,仅用于此目的返回结果。 即使你在循环中这样做,JVM也足够聪明,可以有效地处理它。 Java只会在需要时以非常大的块分配来自操作系统的内存,并且将在内部处理对象创建和释放,而不会产生C / C ++等语言的开销。 “通过引用传递”实际上对Java没有多大帮助。
编辑:我建议你在这个论坛或网上搜索术语“副作用”,“函数式编程”或“不变性”。 这很可能会为您的问题打开一个新的视角。
我认为使用作为方法参数的单元素数组“返回”值是不好的做法。
这是关于这个主题的另一个问题 。 简而言之,它的可读性非常糟糕。
有一个简单的解决方法:在您专门为此目的定义的类中包装要返回的所有值,并返回该类的实例。
return new ValueHolder(someValue1, someValue2, someValue3);
这不是非常惯用的java。 通常有更好的软件设计方法。
你真正用“单元素数组”做的是创建一个可变对象(因为String是不可变的,就像int这样的基元)并通过引用传递它。 修改此可变对象称为该方法的“副作用”。 通常,您应该最小化可变性( Effective Java Item 15 ),并且您的方法应该是无副作用的。 这里有几种方法。
public static int foo1(int param1)
{
// method body
....
return <some value>;
}
同样,你可能有
public static int foo2(int param1) { ... }
和
public static String foo3(int param1) { ... }
。
public Container {
private final int originalReturn;
private final int param2;
private final String param3;
public Container(int originalReturn, int param2, String param3) {
this.originalReturn = originalReturn;
this.param2 = param2;
this.param3 = param3;
}
// getters
}
public static Container foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
return new Container(<some value>, <some value>, <some value>);
}
如果值不相关,这确实是不好的做法。 这通常是一个指示器,您可以将该功能拆分为两个,每个返回一个值。
编辑:
我假设您要返回在数组中的方法中计算的两个值。 这不是这种情况吗?
例如
public int[] getStatistics(int[] nums)
{
//code
int[] returns = new int[2];
returns[0] = mean;
returns[1] = mode;
return returns;
}
上面的函数可以分为getMean()
和getMode()
。
通过引用传递变量允许函数“合法地”改变它们的值。 请参阅此文章以清除Java中何时可能出现的混淆,以及何时不...
如果值具有不同类型和不同实体(例如名称和地址等),这是不好的做法。创建具有相同数据类型的数组(例如地址列表)就可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.