Подтвердить что ты не робот

Заключительные классы на Java, которые не должны быть окончательными или наоборот?

Меня недавно задали этот вопрос в интервью:

Можете ли вы назвать любой класс API Java, который является окончательным, который не должен быть, или тот, который не является и должен быть??

Я не мог думать ни о чем. Вопрос подразумевает, что я должен знать все классы API, такие как задняя часть моей руки, которые я лично не ожидал бы, чтобы какой-либо разработчик Java знал.

Если кто-либо знает какие-либо такие классы, просьба привести примеры.

4b9b3361

Ответ 1

Первые примеры, которые приходят на ум, - это некоторые из нечетных подклассов Number, таких как BigDecimal и BigInteger, который, вероятно, должен был быть окончательным.

В частности, все их методы могут быть переопределены. Это позволяет создать сломанный BigDecimal, например:

public class BrokenBigDecimal extends BigDecimal {
    public BigDecimal add(BigDecimal augend) {
        return BigDecimal.ZERO;
    }
}    

Это может вызвать серьезные проблемы, если вы получаете BigDecimal из ненадежного кода, например.

Перефразировать эффективную Java:

  • Дизайн и документ для наследования или запрет на него
  • Классы должны быть неизменными, если нет веской причины сделать их изменчивыми.

Ответ 2

java.awt.Dimension не является окончательным или неизменным и должен был быть. Все, что возвращает размер (например, объект Window), должно создавать защитные копии, чтобы предотвратить неприятности со стороны вызывающих.

Ответ 3

На мой взгляд, ваш ответ должен был состоять в том, что вопрос вкуса, какие классы должны быть окончательными, а какие нет.

Есть веские причины сделать Integer, Double и String все final.

Есть веские причины жаловаться на это.

Тогда есть BitSet, BitInteger и т.д., которые можно сделать final.

Существует несколько ситуаций, когда классы не являются final, но они также не могут быть расширены разумно, поэтому они, вероятно, должны были быть окончательными.

Чтобы выбрать конкретный класс: BitSet. Это не final, но вы не можете расширять его, чтобы добавить бит shift. Они могли бы также сделать это final или добавить нам такую ​​функциональность.

Ответ 4

Выскакивает класс Date. Это изменяемый простой класс значений (по существу, обертка вокруг long), но хорошая эвристика заключается в том, что простые классы значений должны быть неизменными. Обратите внимание также на его многочисленные устаревшие методы: больше доказательств того, что дизайн был взломан. Изменчивость Date является источником ошибок, требующих дисциплинированного оборонительного копирования.

Ответ 5

тот, который не является и должен быть

Большинство конечных классов в Java разработаны так, чтобы они учитывали соображения безопасности, в целом относительно мало конечных. Например, java.util.String является окончательным по этой причине. Так много других. Некоторые классы w/private c-tor объявляются окончательными (Math, StrictMath), но в этом случае это не имеет значения.

В принципе, если нет проблем с безопасностью, мне все равно, является ли класс окончательным, но вы всегда можете использовать непубличный c-tor w/some factory, что фактически ограничивает возможность подкласса. Обычно это мой предпочтительный способ, поскольку он позволяет пакетно-приватное подклассу.

Вкратце: я не могу думать о конечном классе, которого не должно быть, однако есть некоторые, которые могли бы быть. Например, java.lang.Thread может быть окончательным, возможно, не нужно защищать против злонамеренных clone().

Ответ 6

Проверьте класс String, который является окончательным и, вероятно, должен был быть вашим ответом в интервью.

Проверьте документы.

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html