简体   繁体   中英

When using the getInstance() method of the abstract java.text.NumberFormat class, what is the actual class of the return value?

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!

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.

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".

Why not run...

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

... and find out?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM