Каков фактический класс возвращаемого значения при использовании метода getInstance() абстрактного класса java.text.NumberFormat?

Этот вопрос расширяет вопрос в abstract-class-numberformat-very-confused-about -получить экземпляр. Я чувствую, что этот вопрос достаточно отличается, чтобы его задавали отдельно.

В ответах на этот вопрос было указано, что оператор кода, такой как

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

возвращает объект, являющийся подклассом класса java.text.NumberFormat. Мне понятно, почему возвращаемый тип не может быть просто экземпляром NumberFormat, поскольку это абстрактный класс. Скорее было заявлено, что возвращаемый объект является как минимум экземпляром NumberFormat, но на самом деле чем-то другим.

Мой вопрос заключается в следующем: каков конкретно класс возвращаемого объекта? В документации Sun я вижу только подклассы ChoicesFormat и DecimalFormat. Здесь происходит какое-то закулисное вуду компилятора?

Заранее спасибо!


person chucksmash    schedule 17.05.2010    source источник
comment
Никакого компиляторного вуду, просто старый добрый полиморфизм. :-)   -  person perp    schedule 17.05.2010
comment
Вы можете позвонить System.out.println(en.getClass().getName()), чтобы узнать, что это такое.   -  person Kaleb Brasee    schedule 17.05.2010


Ответы (4)


Конкретный тип не указан, поскольку это может быть любой подкласс NumberFormat. Это может даже зависеть от языка, который вы используете. Для некоторых локалей может потребоваться ChoiceFormat для правильной реализации, для других достаточно DecimalFormat, а для третьих локалей они могут даже вернуть специфичную для локали реализацию.

Тот факт, что он не определен более конкретно, чем абстрактный базовый класс, позволяет вносить подобные изменения в реализацию без необходимости изменения сигнатуры метода для учета такого изменения.

Вы можете легко проверить, какой конкретный тип возвращается одним конкретным вызовом, вызвав getClass() для возвращаемого значения.

person Joachim Sauer    schedule 17.05.2010

Это пример фабричного шаблона.

Разработчики API не хотели требовать, чтобы вызывающая сторона знала конкретный подтип NumberFormat. Если вызывающая сторона «заботится», какие конкретные классы могут быть возвращены, начинают появляться злые вещи, такие как оператор instanceof. Когда происходит подобное, вызывающий объект внезапно становится «тесно связанным» с конкретным подклассом, а не только с «интерфейсом» (где интерфейс может означать интерфейс Java, абстрактный класс или даже какой-либо другой не конечный класс).

Большинство сторонников ООП хотят, чтобы вы добивались «высокой инкапсуляции, слабой связанности».

person jasonnerothin    schedule 17.05.2010

Почему бы не бежать...

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

... и узнать?

person Sean Owen    schedule 17.05.2010
comment
хороший вопрос. Мне стыдно признаться, что эта идея даже не пришла мне в голову. Дело принято :) - person chucksmash; 17.05.2010

Использование консоли Beanshell в Jedit, я получаю следующее:

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

Я бы сказал, что DecimalFormat возвращается этим вызовом.

person Andy Gherna    schedule 17.05.2010