В чем разница между наличием класса как final и наличием конструктора класса как частного
В чем же разница между конечным классом и наличием конструктора класса как закрытого.
Я знаю, что оба нельзя подклассифицировать (исправьте меня, если я ошибаюсь). Есть ли у них какая-то разница?
Ответы
Ответ 1
Окончательный класс не может быть расширен. Это предотвращает это
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}
}
Когда вы расширяете класс, ваш конструктор по умолчанию пытается вызвать конструктор по умолчанию (без аргумента). Если это является приватным, тогда вы должны явно вызвать не-частный конструктор при его расширении. Если у вас нет не-частных конструкторов для вызова, вы не сможете его продлить. Спасибо за комментарии за это.: -)
Ответ 2
Инстанцирование
- Вы не можете создать экземпляр класса с помощью частного конструктора. Но вы можете использовать его как класс утилиты со статическими методами.
- Окончательный класс может быть создан, но не расширен, очевидно, вы не можете расширить класс с помощью
частный конструктор, так как неявный вызов super() завершился с ошибкой.
Посмотрите на класс Math, у которого есть частный конструктор, он не может быть создан, но у него много статических методов, которые очень полезны
Ответ 3
Наличие только частных конструкторов сильнее, чем конечный класс.
Подробнее:
Наличие только частных конструкторов в классе A сильно влияет на создание объекта. Обычно вы используете метод factory. Вы все же можете создавать экземпляры A без метода factory, используя трюки, такие как clone() или рефлексивно ссылаясь на частный конструктор. Но подкласс невозможен, потому что конструктор подкласса должен иметь возможность вызвать super()
. Это возможно только внутри вложенного класса внутри A.
Наличие только частных конструкторов часто имеет смысл, например. для управления экземплярами через методы factory, например. для singeltons (см. Эффективный Java-элемент 3). Но даже в этом случае я не вижу причин не писать "окончательный класс", если только для документации, чтобы читатели сразу поняли, что подклассификация не разрешена.
Ответ 4
Если вы не хотите, чтобы ваш класс был подклассифицирован, вы используете final. Если вы не хотите, чтобы другие классы создавали экземпляр класса, а вы хотите контролировать, как объект создается и поддерживается, вы используете частный конструктор.
Ответ 5
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()
Окончательный класс не может быть расширен, но его конструктор может быть общедоступным. Частный конструктор может быть вызван из другого конструктора или использован внутренним классом.
Ответ 6
Последний класс/метод никогда не может быть унаследован/переопределен и будет генерировать ошибку компиляции, когда в качестве класса с частным конструктором будет также выбрана компиляция: "Нет конструктора по умолчанию для вашего класса", и как только вы добавите не окончательный конструктор и вызовите его из вашего дочернего класса. Ошибок не будет.
Частный конструктор полезен в случае создания одноэлементного класса (может существовать только один экземпляр класса), где вы делаете свой конструктор закрытым и переменную для хранения одного экземпляра, который будет открыт публичным статическим методом.
например,
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 является окончательным классом.