Java – Is Using ‘out’ or ‘ref’ Parameters in Java Methods Bad?

coding-standardsjavamutableout-parameters

I happened to create a mutable class like this:

class Mutable<T> {
    private T value;
    public Mutable() { this.value = null; }
    public Mutable(T value) { this.value = value; }
    T get() { return this.value; }
    void set(T value) { this.value = value; }
}

And then it's often used in a method like this:

boolean operation(String input, Mutable<Set<String>> dataOut) throws ... {
    boolean result;
    try {
         String data = doSomething(input);
         result = validate(data);
         if (result && dataOut != null) {
             List<String> values = Arrays.asList(data.split(", "));
             Collections.sort(values);
             dataOut.set(new LinkedHashSet<String>(values));
         }
    } catch(SpecificIgnorableException ex) {
         result = false;
         logger.debug(ex);
    }
    return result;
}

…which is just an example, could be any use case, where one would use ref or out parameters in C#, or non-const reference parameters in C++, or pointers to output parameters in C.

First, same could be done by using an array (with one element) instead of above custom type. Does it make sense to have this custom type which clearly states mutable, instead of using an implicitly mutable array?

Second, is this pattern bad and code smell in Java? Let's limit to cases where using out parameter would make sense in C#. Should every instance of this kind of Java code be replaced? With what?

Best Answer

The real question is "are functions with side-effects bad?"

Providing a reference to an explicit mutable ("out") variable is no different than providing a Map that you modify, or referencing a global variable from within the function. In all three cases, the function is permitted to modify something in a way that is hard to reason about. Consider, for example, a function that modifies the "out" parameter, then throws.

The counter-argument is that this is no different from a method call that modifies an object's private state and then throws.

Personally, if I'm writing a method that is focused on a "result", I would prefer creating a new class to hold it; classes are cheap in Java. If I'm writing a method that modifies an object's internal state, I generally don't return anything from the method.

Related Topic