What is a natural return type in java?

Viewed 496

I am reading Joshua Blochs "Effective Java", and it says

A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type. This gives you great flexibility in choosing the class of the returned object. One application of this flexibility is that an API can return objects without making their classes public. Hiding implementation classes in this fashion leads to a very compact API. This technique lends itself to interface-based frameworks, where interfaces provide natural return types for static factory methods.

Can anyone explain what "natural return types are"? Thanks!

3 Answers

In this context, "natural" simply means natural for the context of the factory method; i.e. what is appropriate or what you would expect. Intuitive would be another synonym.

This is just normal English usage ... not IT or Java-specific terminology.

A concrete example of this would be something like Guava's ImmutableList factory methods.

This has 13 overloads of the of method, with increasing numbers of parameters. If you look at the source of the first 3:

@SuppressWarnings("unchecked")
public static <E> ImmutableList<E> of() {
  return (ImmutableList<E>) EMPTY;
}

public static <E> ImmutableList<E> of(E element) {
  return new SingletonImmutableList<E>(element);
}

public static <E> ImmutableList<E> of(E e1, E e2) {
  return construct(e1, e2);
}

The zero-arg and two-arg methods actually return an instance of RegularImmutableList, which is a subclass of ImmutableList; the one-arg method returns an instance of SingletonImmutableList.

But is this detail about the subclass relevant to you, the caller? No. It is "natural" that if you call a method that constructs an ImmutableList, you get back a reference to an ImmutableList.

"Natural" in this sense perhaps means "at an appropriate level of abstraction".

I think that it refers to the class of the factory (which is usually a static method in the class) which doesn't need to instantiate this specific class. However I don't think it is a defined or usually used term.

Example: Term

public abstract class Term {

    public abstract Integer evaluate();

    static Term literal(Integer number) {
        return new Literal(number);
    }

    static Term add(Term left, Term right) {
        return new Addition(left, right);
    }

    private static class Addition extends Term {
        private Term left;
        private Term right;

        public Addition(Term left, Term right) {
            this.left = left;
            this.right = right;
        }

        @java.lang.Override
        public Integer evaluate() {
            return left + right;
        }
    }

    private static class Literal extends Term {
        private Integer number;

        public Literal(Integer number) {
            this.number = number;
        }

        @java.lang.Override
        public Integer evaluate() {
            return number;
        }
    }
}

This is a class called Term with 2 factory methods: literal and add, which both return a Term but a subclass of it. Term itself is not instantable, because it is abstract. To the outer world the inner classes are not visible (they are private). Accessible is just the interface / abstract class Term, which is what is referred to in

One application of this flexibility is that an API can return objects without making their classes public.

I think the "natural class" to return here would be an Term and new is bound to return an instance of exactly the given type. A factory method can return subtypes.

Example: Guava

Guava is a library which provides additional collection classes for Java. One of these is an immutable list. It contains multiple factory methods for specific cases, for example one for an empty list and an additional one for lists which exactly one element.

I don't think the term "natural class" is "official" though. Without the context (and even with it, as we can see here) it is not sure that it is recognized. So I took your question on a more broader scale and explained what the chapter is about.

Related