В чем же разница между конечным классом и наличием конструктора класса как закрытого.
Я знаю, что оба нельзя подклассифицировать (исправьте меня, если я ошибаюсь). Есть ли у них какая-то разница?
В чем же разница между конечным классом и наличием конструктора класса как закрытого.
Я знаю, что оба нельзя подклассифицировать (исправьте меня, если я ошибаюсь). Есть ли у них какая-то разница?
Окончательный класс не может быть расширен. Это предотвращает это
final class FinalClass {
}
// and later
class ExtendedClass extends FinalClass { // ERROR
}
Это полезно для таких вещей, как String - вы не хотите, чтобы кто-то мог перезаписать логику String, одного из наиболее часто используемых объектов, и быть в состоянии, о, я не знаю, добавляю сети и отправьте все строки, которые вы используете. Это можно сделать, если вы можете расширить строку.
Частный конструктор нельзя вызывать вне класса.
class PrivateCons {
private PrivateCons() {
}
}
// later
PrivateCons pc = new PrivateCons(); // ERROR
Часто это работает следующим образом: (java.lang.Math - хороший пример)
class FuncLib {
private FuncLib() { } // prevent instantiation
public static void someFunc(...) { }
public static int anotherFunc(...) { }
}
Или он работает так://Integer делает это на самом деле
class VerySpecial {
private static Map<String,VerySpecial> cache;
public static VerySpecial generate(String data) {
VerySpecial result = cache.get(data);
if(result == null) {
result = new VerySpecial(data);
cache.put(data,result);
}
return result;
}
private String data;
private VerySpecial() { }
private VerySpecial(String data) { this.data = data}
}
Когда вы расширяете класс, ваш конструктор по умолчанию пытается вызвать конструктор по умолчанию (без аргумента). Если это является приватным, тогда вы должны явно вызвать не-частный конструктор при его расширении. Если у вас нет не-частных конструкторов для вызова, вы не сможете его продлить. Спасибо за комментарии за это.: -)
Посмотрите на класс Math, у которого есть частный конструктор, он не может быть создан, но у него много статических методов, которые очень полезны
Наличие только частных конструкторов сильнее, чем конечный класс.
Подробнее:
Наличие только частных конструкторов в классе A сильно влияет на создание объекта. Обычно вы используете метод factory. Вы все же можете создавать экземпляры A без метода factory, используя трюки, такие как clone() или рефлексивно ссылаясь на частный конструктор. Но подкласс невозможен, потому что конструктор подкласса должен иметь возможность вызвать super()
. Это возможно только внутри вложенного класса внутри A.
Наличие только частных конструкторов часто имеет смысл, например. для управления экземплярами через методы factory, например. для singeltons (см. Эффективный Java-элемент 3). Но даже в этом случае я не вижу причин не писать "окончательный класс", если только для документации, чтобы читатели сразу поняли, что подклассификация не разрешена.
Если вы не хотите, чтобы ваш класс был подклассифицирован, вы используете final. Если вы не хотите, чтобы другие классы создавали экземпляр класса, а вы хотите контролировать, как объект создается и поддерживается, вы используете частный конструктор.
private
Доступ к элементам осуществляется через внутренние классы.
public class Outer {
private Outer() {
System.out.println("Outer()");
}
static class Inner extends Outer {
{
System.out.println("Inner()");
}
}
public static void main(String... args) {
new Inner();
}
}
печатает
Outer()
Inner()
Окончательный класс не может быть расширен, но его конструктор может быть общедоступным. Частный конструктор может быть вызван из другого конструктора или использован внутренним классом.
Последний класс/метод никогда не может быть унаследован/переопределен и будет генерировать ошибку компиляции, когда в качестве класса с частным конструктором будет также выбрана компиляция: "Нет конструктора по умолчанию для вашего класса", и как только вы добавите не окончательный конструктор и вызовите его из вашего дочернего класса. Ошибок не будет.
Частный конструктор полезен в случае создания одноэлементного класса (может существовать только один экземпляр класса), где вы делаете свой конструктор закрытым и переменную для хранения одного экземпляра, который будет открыт публичным статическим методом. например,
public class Singleton{
private static final Singleton instance = new Singleton();
//private constructor to avoid client applications to use constructor
private Singleton(){}
public static Singleton getInstance(){
return instance;
}}
И, например, класс String в java является окончательным классом.