这个问题扩展了 abstract-class-numberformat-very-confused-about 上的问题-获取实例。我觉得这个问题足够不同,值得单独提出。
在该问题的答案中,指出诸如之类的代码语句
NumberFormat en = NumberFormat.getInstance(Locale.US);
返回一个对象,该对象是 java.text.NumberFormat
类的子类。对我来说,为什么返回类型不能只是 NumberFormat
的实例,因为它是一个抽象类。相反,据说返回的对象至少是NumberFormat
的一个实例,但实际上是其他东西。
我的问题是:返回的对象的类具体是什么?在 Sun 文档中,我看到的唯一子类是 ChoicesFormat
和 DecimalFormat
。这里是否存在某种幕后编译器巫术?
提前致谢!
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!
发布评论
评论(4)
具体类型没有指定,因为它可以是
NumberFormat
的任意子类。它甚至可能取决于您使用的区域设置。某些语言环境可能需要ChoiceFormat
才能正确实现,而对于其他语言环境,DecimalFormat
就足够了,对于第三种语言环境,它们甚至可能返回特定于语言环境的实现。事实上,它的定义并不比抽象基类更具体,因此允许在实现中进行这种更改,而无需更改方法签名来适应这种更改。
您可以通过对返回值调用
getClass()
来轻松验证一个特定调用返回的是哪种具体类型。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 aChoiceFormat
to implement correctly, for othersDecimalFormat
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.这是工厂模式的一个例子。
API 设计者不想要求调用者知道 NumberFormat 的具体子类型。如果调用者“关心”可能返回哪些具体类,那么像instanceof运算符这样的邪恶事物就会开始出现。当发生类似的事情时,调用者突然与具体子类“紧密耦合”,而不仅仅是“接口”(其中接口可以表示 Java 接口、抽象类甚至其他一些非最终类)。
大多数面向对象的拥护者希望您追求“高封装、松耦合”。
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...
... and find out?
在 Beanshell 控制台>Jedit,我得到以下信息:
我想说 DecimalFormat 是由该调用返回的。
Using the Beanshell console in Jedit, I get the following:
I would say that DecimalFormat is returned by that call.