Reputation: 5997
i have a method which will return an error code(int) and a result(int). If the error code is 0, the result is valid. In c++, this may like:
int method(int& result);
Java calls by reference, so if we change a object in a method, the change is visible by the caller. But, int is not a class, so I could't make is like this in java:
int method(int result);
And Integer and Long are immutable in Java, so change is not visible by the caller if i do it like this:
Integer method(Integer result);
Wrap the result into a Wrapper Class works! But, that's no so simple!
I work with c++ for long and move to java recently, this bother me a lot! could any one provide a solution?
=================================
well, in a conclusion, there are these flowing solutions:
1st and 2nd make my api ugly 3rd and 4th seems not so perfect about 5th, this method is frequantly called so i've to take efficiency into consideration 6th seems match my require most
thanks!
Upvotes: 5
Views: 6643
Reputation: 533690
In your case, if you have a error, throw an appropriate exception. You have exceptions in C++ also.
Anything else is a valid result.
However to answer your question on how to return multiple values.
An approach I use in many places is to use a listener interface
interface ErrorOrResult {
void onError(int error);
void onResult(int result);
}
a.method(errorOrResultImpl); // can use an anonymous implementation here.
As you can see, different types of result can be called any number of times with a variety of arguments.
You could return a Object with two fields. This is the most object orientated way.
If it bothers you that an object is created each time, you can pass an object as an argument.
The simplest being an int[]
which you reuse.
int[] results = { 0, 0 };
a.method(results);
An alterative is to return a long.
long result = a.method();
// split into two int values.
Or to make the method stateful.
int error = a.method();
int result = a.methodResult();
Or you can use the sign like Collections.binarySearch does
int errorOrResult = a.method();
if (errorOresult < 0)
int error = ~errorOrResult;
else
int result = errorOrResult;
Given there are so many alternatives, it may a while before multiple return values are allowed.
Upvotes: 0
Reputation: 147164
Firstly, an int
error code? Generally considered poor in Java. Exception is usual (but slow when executed). If it's actually common and/or performance is critical, then return something meaningful. Perhaps a nice new [2004] enum.
So in general, how to return multiple values. You could hack it and use AtomicInteger
or similar. Please don't use an array!
Better would be to return a meaningful (probably immutable) object. Pair<,>
is not a meaningful object. (There have been some suggestions for making this easier in a future version of the language.)
A more exotic way is to pass in a callback object. this is particularly useful if the result data differs depending upon possible result types. Have the method return void
(or possibly the result of the callback) and add a parameter. Call a method depending upon the result type. Add as many arguments (within taste) and methods as useful. A typical caller would use an anonymous inner class, and not have to switch on error code. Of course, returning to the enclosing method again raises the problem of how to get the data out.
Upvotes: 0
Reputation: 69372
There's a MutableInt component in the Apache Commons library. Since it's mutable, you can pass it by reference.
Upvotes: 0
Reputation: 17864
Return an object containing the two integers, eg. using commons-lang v3 Pair
Pair<Integer, Integer> method(){
return Pair.of(a,b)
}
Upvotes: 0
Reputation: 11257
Returning an error code is not a good practice in Java. Instead use exceptions... And list for multiuple values...
List<Integer> method(Parameter... paramteters)
{
List<Integer> listOfValues = ...
//some calculations
if(errorCondition) throw new SomeException();
//more calculations, if needed
return listOfValues;
}
Upvotes: 0
Reputation: 167
There are two ways to handle the scenario :- 1. Have a special values for error codes to distinguish them from result values ( if that is possible). For example, the indexOf() method in java's ArrayList returns -1 if the element is not present in the list, otherwise returns the positive index. 2. Use exceptions for erroneous conditions and always treat the return value as correct result. That is, if the method returns without any exception, assume exit code to be 0 and store the return value into result.
Creating a custom object to store the result and exit code might be an overkill.
Upvotes: 1
Reputation: 10151
I would suggest creating a custom Object to hold both pieces of data, e.g.
public class ResultData {
private int result;
private int errorCode;
public ResultData(int errorCode, int result) {
this.result = result;
this.errorCode = errorCode;
}
// Getters...
}
Then your method becomes:
public ResultData method() {
// Do stuff
return new ResultData(error, result);
}
Alternatively, as other answers have suggested, use Exceptions to signify if an error has occurred and that way if the method returns a result you can always be sure that it is valid. Catching the Exception signifies that an error occurred and you can handle it the way you would have handled the errorCode.
Upvotes: 1
Reputation: 109124
Don't use return codes for errorcodes: use Exceptions; it is what they are for. Just return the actual result.
Upvotes: 4
Reputation: 52185
You can't return more than one integer for your method. What you can do is:
Create a new object with 2 integer fields and let your method return an instance of that object (basically a wrapper);
Make your method return an array of 2 integers (or take it as a parameter);
Make your method return a String variable of the form <int 1>,<int 2>
. You can then use the split() to get the numbers from the string and parse them back to integers.
Make your method throw the exception and return the number.
Upvotes: 3
Reputation: 2969
You are correct that you would need to wrap the values. If the call to method
will not be too frequent, consider throwing an exception to report failure and exit cleanly otherwise. That would be the most Java-esque approach. I use this pattern in my C++ code as well (I do not like output parameters and return values in the same method unless there are other pressures requiring it).
However, performance sometimes requires the more C-system-call-ish style you are using. In that case I recommend you construct a Result type and an Error type that you can set the value of.
Something else to consider is to have a Generic (read "templated") class named TwoTuple<TYPE1, TYPE2>
that you can use to pass pairs of values around. I've found that in Java I do a lot of pair-passing, though that might be a derivative of my personal style. :)
Upvotes: 2
Reputation: 62459
Not very nice, but:
int method(int[] result) {
result[0] = 1; // set result[0] as your out value
// etc.
}
Using an array to create an "artificial reference" towards a single int.
Upvotes: 0