В чем именно разница между окончательным классом и наличием конструктора класса как частного.
Я знаю, что оба не могут быть подклассами (поправьте меня, если я ошибаюсь). Есть ли у них разница?
В чем именно разница между окончательным классом и наличием конструктора класса как частного.
Я знаю, что оба не могут быть подклассами (поправьте меня, если я ошибаюсь). Есть ли у них разница?
Окончательный класс не может быть расширен. Это предотвращает это
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 является конечным классом.