views:

156

answers:

4

This question expands upon the one at abstract-class-numberformat-very-confused-about-getinstance. I feel that this question is different enough to merit being asked on its own.

In the answers to that question, it was stated that a code statement such as

NumberFormat en = NumberFormat.getInstance(Locale.US);

returns an object that is a subclass of the java.text.NumberFormat class. It makes sense to me why the return type can't be just an instance of NumberFormat since that is an abstract class. Rather, it was stated that the returned object is at least an instance of NumberFormat, but actually something else.

My question is this: what specifically is the class of the object that is returned? In the Sun documentation the only subclasses I see are ChoicesFormat and DecimalFormat. Is there some sort of behind the scenes compiler voodoo going on here?

Thanks in advance!

A: 

Why not run...

System.out.println(NumberFormat.getInstance(Locale.US).getClass().getName());

... and find out?

Sean Owen
good question. I'm embarrassed to say that the idea didn't even occur to me. point taken :)
A: 

Using the Beanshell console in Jedit, I get the following:

BeanShell> import java.text.NumberFormat;
BeanShell> NumberFormat en = NumberFormat.getInstance(Locale.US);
BeanShell> en.getClass().getName();
java.text.DecimalFormat

I would say that DecimalFormat is returned by that call.

Andy Gherna
+2  A: 

The specific type is not specified, because it can be any subclass of NumberFormat. It might even depend on the locale you use. Some locales may require a ChoiceFormat to implement correctly, for others DecimalFormat is sufficient and for a third locale they might even return a locale-specific implementation.

The fact that it's not defined more specifically than the abstract base class allows this kind of change in the implementation without having to change the method signature to accommodate such a change.

You can easily verify which concrete type is returned by one specific call by calling getClass() on the returned value.

Joachim Sauer
+1  A: 

This is an example of factory pattern.

The API designers didn't want to require the caller to know the concrete subtype of NumberFormat. If the caller "cares" what concrete classes may be returned Evil Things like the instanceof operator start appearing. When stuff like that happens, all the sudden the caller is "tightly coupled" to the concrete subclass and not just the "interface" (where interface can mean a Java interface, abstract class or even some other non-final class).

Most OO advocates want you to shoot for "high encapsulation, loose coupling".

jasonnerothin