Sometimes you want to return multiple values from a function. How is this normally done in Java?
One option is to use an array, like this Python snippet that returns a list or tuple:
value, success = read_unreliably()
if success:
print value
Another option would be to return a hash/dict, like this JavaScript example:
var result = readUnreliably()
if (result.success) {
alert(value);
}
One more would be to create a custom object just for this purpose, like this Java example:
ReadUnreliablyResult result = readUnreliably()
if (result.getSuccess()) {
System.out.println(result.getValue());
}
Of course you can also just use some global variables to store what you need instead of passing things around, but let's just say that's not an option.
-
Do "real" java people really go through the trouble of using public getters and setters to hide fields on little internal classes like that? Just curious.Chris Farmer– Chris Farmer2011年07月25日 23:50:59 +00:00Commented Jul 25, 2011 at 23:50
-
3Yes, most do. Since many frameworks expect the JavaBean standard, you can regret not having getters and setters. In any case, your IDE will generated them for you.Eric Wilson– Eric Wilson2011年07月26日 02:34:36 +00:00Commented Jul 26, 2011 at 2:34
-
3Or you can just leave them out, based on the YAGNI principle. But that doesn't seem to happen as often as one might expect.Tyler– Tyler2011年07月26日 02:46:02 +00:00Commented Jul 26, 2011 at 2:46
-
@FarmBoy: I guess I understand for beans and such, but the OP implies that this is just a one-off class designed to return multiple values.Chris Farmer– Chris Farmer2011年07月26日 17:03:30 +00:00Commented Jul 26, 2011 at 17:03
-
@ChrisFarmer I guess that with that context, I've never seen a 'real' Java programmer create a class for this purpose.Eric Wilson– Eric Wilson2011年07月26日 18:22:07 +00:00Commented Jul 26, 2011 at 18:22
6 Answers 6
How is this normally done in Java?
Painfully.
One option is to use an array, like this Python snippet that returns a list or tuple...
Another option would be to return a hash/dict, like this JavaScript example...
These techniques don't work well in Java; the values would have to be downcast from Object.
One more would be to create a custom object just for this purpose, like this Java example...
This is most common, but it is tedious to create all those little classes. In C++ it is common to use std::pair but this is not commonly done in Java.
With Lombok it is quite easy to create little custom objects:
@RequiredArgsConstructor
public class X {
private final boolean status;
private final byte[] data;
}
-
10"How is this normally done in Java?" "Painfully." lol as a Java developer I have to +1 you for thatTheLQ– TheLQ2011年07月26日 06:16:27 +00:00Commented Jul 26, 2011 at 6:16
-
Using a compact immutable struct-like class is not so painful... It is really like writing a C struct...Guillaume– Guillaume2011年07月26日 14:34:12 +00:00Commented Jul 26, 2011 at 14:34
-
1@Guillaume - sure, but all those little things add up in both time and space. I don't know why the Java community hasn't adopted a standard set of generics like "class Pair<T1,T2> { public T1 first; public T2 second; ... }"; in modern languages you just "return a, b" ; and then write "x,y=f()";kevin cline– kevin cline2011年07月26日 14:55:11 +00:00Commented Jul 26, 2011 at 14:55
-
1I'm sure some 'ancient' language are able to do it too :) IMHO I found multiple return values can lead to total mess, and if you need to add another return fields, you just have to update your struct like class without to change your method signature.Guillaume– Guillaume2011年07月26日 15:24:52 +00:00Commented Jul 26, 2011 at 15:24
-
1That "Painfully." struck me hard, yes its exactly what I feel as Java developer when I meet similar situations.artjom– artjom2013年09月25日 10:19:55 +00:00Commented Sep 25, 2013 at 10:19
Yes, the way to create a struct
/ tuple
/ record
in Java is by creating a class. If it's only for internal use, I prefer to use a small immutable struct-like class with public fields.
Examples:
public class Unreliably {
public final boolean success;
public final int value;
public Unreliably(boolean success, int value) {
this.success = success; this.value = value;
}
}
This is much easier to do in Scala:
case class Unreliably(success: Boolean, value: Int)
-
8Actually, in Scala, you'd probably generally just return a
Tuple2[Boolean, Int]
. Although in this specific example, you'd return anOption[Int]
.Jörg W Mittag– Jörg W Mittag2011年07月26日 00:48:40 +00:00Commented Jul 26, 2011 at 0:48 -
2So this answers Chris Farmer's question (in the Q's comments) that real Java people don't necessarily create getters and setters for little internal classes. You are a "real" Java person, right?Mike M. Lin– Mike M. Lin2011年07月26日 03:14:09 +00:00Commented Jul 26, 2011 at 3:14
-
2In other news, there are no true Scotsmen.Joseph Weissman– Joseph Weissman2011年07月26日 04:10:59 +00:00Commented Jul 26, 2011 at 4:10
For the example you have given, throwing an exception would be the most standard way to handle it:
try {
result = readUnreliably();
System.out.println(result);
} (catch IOException e) {
System.out.println("Could not read file");
}
Moreover, if you strive to have functions that "Do One Thing" the feature of returning multiple values is less necessary, though occasionally convenient.
We have a Pair generic class which can store one instance of A and one instance of B. You can probably create a Triplet or Quadruplet in the same manner.
public class Pair<A, B>
{
...
}
-
1this makes for some REALLY unreadable code though. if a method returns
Pair<String, Integer>
, what does that mean? what do these values represent? you can't possibly know without reading the implementation of the method.sara– sara2016年03月22日 09:57:11 +00:00Commented Mar 22, 2016 at 9:57
In Java, your function would return an object (or perhaps null in the case of a failure). This way, multiple pieces of data can be returned.
There is no explicit way to return multiple variables in Java, however there are a few approaches:
- The first is to go the way of the array. This only really works if you have everything as the same data type or can temporarily convert them to one type.
- The second way is to create a class for the purpose of transferring multiple variable types. At my work we refer to these as DTOs or Data Transfer Objects.