В чем именно разница между окончательным классом и наличием конструктора класса как частного.
Я знаю, что оба не могут быть подклассами (поправьте меня, если я ошибаюсь). Есть ли у них разница?
В чем именно разница между окончательным классом и наличием конструктора класса как частного.
Я знаю, что оба не могут быть подклассами (поправьте меня, если я ошибаюсь). Есть ли у них разница?
Окончательный класс не может быть расширен. Это предотвращает это
final class FinalClass {
}
// and later
class ExtendedClass extends FinalClass { // ERROR
}
Это полезно для таких вещей, как String — вы бы не хотели, чтобы кто-то мог перезаписать логику 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, у него есть частный конструктор, он не может быть создан, но у него есть много статических методов, которые очень полезны.
this
.)
- person toto2; 07.09.2011
Constructor.newInstance()
(после смены доступа), но не MyClass.class.newInstance()
- person Peter Lawrey; 07.09.2011
Если вы не хотите, чтобы ваш класс был подклассом, используйте final. Если вы не хотите, чтобы другие классы создавали экземпляр вашего класса, а хотите контролировать, как создается и поддерживается объект, вы используете частный конструктор.
Наличие только частных конструкторов сильнее, чем наличие конечного класса.
Подробно: наличие только частных конструкторов в классе A сильно влияет на создание объекта. Обычно вы используете фабричный метод. Вы по-прежнему можете создавать экземпляры A без фабричного метода, используя приемы, такие как clone() или рефлексивный вызов закрытого конструктора. Но подклассы невозможны, потому что конструктор подкласса должен иметь возможность вызывать super()
. Это было бы возможно только внутри вложенного класса внутри A.
Часто имеет смысл иметь только частные конструкторы, например. для управления экземплярами с помощью фабричных методов, например. для синглтонов (см. Эффективный Java, пункт 3). Но даже в этом случае я не вижу причин не писать «окончательный класс», хотя бы для документации, чтобы читатели сразу поняли, что создание подклассов не разрешено.
Доступ к 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 является конечным классом.