我有时(实际上,经常)发现自己使用单元素数组从方法返回多个值。像这样:
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秒!)
但我首先使用它的原因是因为它看起来与C ++中的pass-by-reference
最接近。 C++
并没有气馁这种做法,所以......
但如果这确实是一种错误的做事方式,那么任何想法如何以干净的方式重写它?
由于
答案 0 :(得分:6)
创建一个包含要返回的数据的对象。
然后您可以返回该对象的实例。
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;
}
答案 1 :(得分:5)
虽然我同意这里的一般意见,为此目的使用数组是不好的做法,但我想补充一些内容。 您确定首先通过“参考传递”确实是您所需要的吗? 很多人说你的代码风格不好,但现在让我告诉你为什么那是恕我直言。 “通过引用传递”主要是“通过副作用编程”的同义词,这是你总是想要避免的事情。它使代码更难以调试和理解,并且在多线程环境中,这种态度的不良影响确实会给你带来困难。 要在Java中编写可伸缩且线程安全的代码,您应该尽可能地使对象“只读”,即理想情况下,您创建一个对象并同时对其进行初始化,然后在整个应用程序中使用此不可修改的状态。对状态的逻辑变化几乎总是被认为是新状态的“创建”,即创建初始化为当时所需状态的新实例。许多现代脚本语言只允许您以这种方式工作,它使事情更容易理解。 与C ++相反,Java在分配和释放短期对象方面效率更高,因此其他人建议的内容实际上没有任何问题:创建一个特殊类的实例来保存函数结果,仅用于此目的返回结果。即使你在循环中这样做,JVM也足够聪明,可以有效地处理它。 Java只会在需要时以非常大的块分配来自操作系统的内存,并且将在内部处理对象创建和释放,而不会产生C / C ++等语言的开销。 “通过引用传递”对Java非常有用。
编辑:我建议你在这个论坛或网上搜索术语“副作用”,“函数式编程”或“不变性”。这很可能会为您的问题打开一个新的视角。答案 2 :(得分:4)
我认为使用作为方法参数的单元素数组“返回”值是不好的做法。
这是关于此主题的another SO question。简而言之,它的可读性非常糟糕。
有一个简单的解决方法:在您专门为此目的定义的类中包装您希望返回的所有值,并返回该类的实例。
return new ValueHolder(someValue1, someValue2, someValue3);
答案 3 :(得分:3)
这不是非常惯用的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>);
}
答案 4 :(得分:2)
如果值不相关,这确实是不好的做法。这通常是一个指示器,您可以将该函数拆分为两个,每个函数返回一个值。
编辑:
我假设您要返回在数组中的方法中计算的两个值。情况不是这样吗?
e.g。
public int[] getStatistics(int[] nums)
{
//code
int[] returns = new int[2];
returns[0] = mean;
returns[1] = mode;
return returns;
}
上述功能可以分为getMean()
和getMode()
。
答案 5 :(得分:1)
通过引用传递变量允许函数“合法地”改变它们的值。请参阅this article以清除Java中何时可能存在的混淆,以及何时不能......
答案 6 :(得分:1)
如果值具有不同类型和不同实体,则这是不好的做法,例如名称和地址等。创建一个具有相同数据类型的数组,例如地址列表。