0

How to pass a OUT String parameter to a function ? something like

public static Address getFromLocation (OUT string ErrorMsg) { ... }

If some errors are found in the getFromLocation then the function will update the ErrorMsg that i can use later.

If it's not possible, how in my example, can i retrieve the errorMsg ?

zeus
  • 12,173
  • 9
  • 63
  • 184
  • 2
    There is no such thing as an `OUT` parameter in Java –  Sep 20 '18 at 13:07
  • Java is pass-by-value, `String`s are immutable and `OUT` is not a valid keyword in Java. – Mena Sep 20 '18 at 13:08
  • What language are you comparing against? – karen Sep 20 '18 at 13:08
  • @mena so how i can do in my scenario to retrieve the error message ? – zeus Sep 20 '18 at 13:09
  • 1
    The duplicate is too general, the question is a lot more specific than what's described there. Pointing to "is java pass by value or by reference" is very much like suggesting to use google. Voting to re-open. – Sergey Kalinichenko Sep 20 '18 at 13:09
  • 2
    You may consider throwing an `Exception` with a message, then `catch` it where the method is called. – Arnaud Sep 20 '18 at 13:11
  • @loki you can either make it a property of the returned object if that makes any sense, choose to return that `String` instead of what ever the `Address` is, throw an `Exception` with that message if that is applicable, or mutate a mutable argument of the method (i.e. not a `String`) by injecting that `String` in it somehow (the latter would be highly recommended against as it follows hard-to-debug imperative-styled idioms). – Mena Sep 20 '18 at 13:12
  • @Mena: "mutate a mutable argument of the method (i.e. not a String) by injecting that String in it" ... hmm how to do this ? i m new to java – zeus Sep 20 '18 at 13:15
  • 1
    @loki any object that has setters is implicitly mutable. If you pass an instance of say `MyObject` as an argument to the method and invoke something like `setErrorMessage(String something)` against that object in the method's body, references to that object outside the method's scope will point to the updated instance where that property is now set. Again though, I'd personally recommend against that approach. – Mena Sep 20 '18 at 13:17

3 Answers3

1

Java doesn't have "out" parameters.

There are a couple of standard(ish) ways to do this (report back an error) in Java:

  1. Throw an exception, perhaps of a type defined specifically for this purpose, with the details in the exception.

  2. Very much second best: Return an object with a property for the address and a property for the error string; in the successful case fill in the address and left the error string null, and in the error case fill in the error string and leave the address null.

  3. Pass a List<String> or similar into the method (thanks a_horse_with_no_name for the reminder), and add to the list in the error case, returning null for the Address.

...or various variations on those themes.

#1 and #3 are vastly preferable to #2. #1 provides for structured exception handling. (For instance, the method calling getFromLocation may choose not to handle the exception and instead to document that it may throw that exception, leaving error handling to its caller.) #3 is particularly useful when you have a lot of methods like this and the error case is common (user input validation), and you want to present a series of errors.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Third: pass a List that will be filled with error messages. I use that to e.g. pass "informational message" back to the caller that might not qualify as an error –  Sep 20 '18 at 13:12
  • 4. (almost same as 2) two different objects (implementing same interface) , one for positive with additional information, other for error, with message – user85421 Sep 20 '18 at 13:13
1

One way in Java would be:

public void foo(List<String> bar) { ...

but, more reasonable:

public String foo() { ...

In other words:

  • Java is pass by value
  • so you can only pass a reference to a String object
  • but String objects are immutable!
  • so you can't OUT via parameter
  • you can only return a string
  • or (ugly hack) pass a "some sort of container" (for example a list of strings), and push your string into that container object.

In the end, the real answer is: a method should do one thing. If your method has to A) return some value and B) "out return" another value, then it is obviously doing two things, thus violating the Single Responsibility Principle.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

There is no such thing as an out parameter in Java, so you have to imitate passing output parameters with pass-by-value by adding an extra level of indirection.

A very simple approach is passing a StringBuilder - a mutable object which could be modified by the caller:

public static Result getFromLocation(StringBuilder additionalInformation) {
    ...
    // Method modifies the mutable object
    additionalInformation.append("Some additional text");
    ...
}

The caller would have to provide a non-null StringBuilder, like this:

StringBuilder info = new StringBuilder();
Result res = getFromLocation(info);
// Caller sees information inserted by the method
System.out.println(info);

In situations when you receive back an error message, a better approach is to throw a checked exception. This way you would be able to provide the error message out of bounds, and cleanly separate error processing from the code for the main functionality of your system:

class AddressRetrievalExcepion extends Exception {
    ...
}
public static Address getFromLocation() throws AddressRetrievalExcepion {
    ...
    if (errorCondition) {
        throw new AddressRetrievalExcepion("Cannot get address");
    }
    ...
}

try {
    Address addr = getFromLocation(error);
} catch (AddressRetrievalExcepion ae) {
    System.out.println(ae.getMessage());
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    The solution with a mutable object is pretty horrible through. – Mena Sep 20 '18 at 13:19
  • 1
    @Mena Java does not give you much option, though: it's either a list or a mutable "something" - in this case, a "mutable string", AKA `StringBuilder`. It's not that horrible by itself, but in the context of error processing it's a big no-no. I re-worked the code to make sure it does not look like error processing. – Sergey Kalinichenko Sep 20 '18 at 13:21
  • I can't disagree, but changes in how Java works since Java 8 allow a "closer-to-functional" programming style, with many advantages over imperative programming style. Passing an argument to a method for the sole purpose of having caller references to that object updated by the method's internal processing (instead of manipulating the returned value or throwing exception) smells to me like an outdated and potentially dangerous programming practice. And we're still within a single-threaded context here, but you know where I'm going... – Mena Sep 20 '18 at 13:26
  • 1
    @Mena It's not simply "outdated", it's ["Real Programmer can write FORTRAN programs in any language"](http://web.mit.edu/humor/Computers/real.programmers)-outdated :-) :-) :-) However, the demand is there, so I mentioned it anyway. – Sergey Kalinichenko Sep 20 '18 at 13:34
  • whoa, for a brief moment I wasn't sure whether it was satire XD. – Mena Sep 20 '18 at 13:39