Почему конструкторы не могут быть окончательными - PullRequest
73 голосов
/ 28 февраля 2012

Почему конструкторы не могут быть конечными, статическими или абстрактными в Java?

Например, вы можете объяснить мне, почему это недействительно?

public class K {

    abstract public K() {
        // ...
    }
}

Ответы [ 10 ]

154 голосов
/ 28 февраля 2012

Когда вы устанавливаете метод как final, это означает: «Я не хочу, чтобы какой-либо класс переопределял его». Но в соответствии со спецификацией языка Java:

JLS 8.8 - "Объявления конструктора не являются членами. Они никогда не наследуются и, следовательно, не подлежат скрытию или переопределению."

Когда вы задаете метод как abstract, онозначает: «Этот метод не имеет тела, и его следует реализовать в дочернем классе.» Но конструктор вызывается неявно, когда используется ключевое слово new, поэтому у него не может быть тела.

Когда вы устанавливаете метод как static, это означает: "Этот метод принадлежит классу, а не конкретному объекту." Но конструктор неявно вызывается для инициализации объекта,поэтому нет смысла иметь статический конструктор.

39 голосов
/ 28 февраля 2012

На самом деле вопрос в том, почему вы хотите, чтобы конструктор был static or abstract or final.

Конструкторы не наследуются, поэтому их нельзя переопределить, поэтому зачем использовать финальный конструктор

Конструктор вызывается автоматически при создании экземпляра класса, он имеет доступ к полям экземпляра класса.Что будет использовать статический конструктор.

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

14 голосов
/ 28 февраля 2012

Java-конструктор неявно final, статические / нестатические аспекты его семантики неявно 1 и бессмысленно , чтобы конструктор Java был абстрактным.

Это означает, что модификаторы final и static будут избыточными, а ключевое слово abstract не будет иметь никакого значения вообще.

Естественно, разработчики Java не видели в какой-либо моменте возможности использования избыточных и / или бессмысленных модификаторов доступа для конструкторов ... поэтому они не допускаются грамматикой Java.

В сторону: Обидно, что они не сделали тот же самый вызов дизайна для методов интерфейса, где модификаторы public и abstract также избыточны, но разрешены в любом случае.Возможно, есть какая-то (древняя) историческая причина для этого.Но в любом случае его нельзя исправить, не сделав (возможно) миллионы существующих Java-программ некомпилируемыми.


1 - На самом деле конструкторы имеют смесь статической и нестатической семантики.Вы не можете "вызвать" конструктор в экземпляре, и он не наследуется и не может быть переопределен.Это похоже на работу статических методов.С другой стороны, тело конструктора может ссылаться на this и вызывать методы экземпляра ... как метод экземпляра.И затем есть цепочка конструктора, которая является уникальной для конструкторов.Но реальная суть в том, что эта семантика фиксирована, и нет смысла разрешать избыточный и, вероятно, сбивающий с толку модификатор static.

9 голосов
/ 08 марта 2014
  • public конструктор : объекты могут быть созданы где угодно.

  • конструктор по умолчанию : объекты могут бытьсоздается только в том же пакете.

  • protected конструктор : объекты могут создаваться классами вне пакета, только если это подкласс.

  • private конструктор : Объект может быть создан только внутри класса (например, при реализации синглтона).

* 1030Ключевые слова *, final и abstract не имеют значения для конструктора, поскольку:

  • static члены принадлежат классу, но конструктор необходим для создания объекта.

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

  • final ограничивает модификацию: переменные становятся постоянными, методы не могут быть переопределены, а классы не могут быть унаследованы.

6 голосов
/ 30 июля 2015

Конструкторы НИКОГДА не могут быть объявлены как окончательные.Ваш компилятор всегда выдаст ошибку типа «модификатор final не разрешен». Final, когда применяется к методам, означает, что метод не может быть переопределен в подклассе.Конструкторы НЕ являются обычными методами.(применяются разные правила) Кроме того, конструкторы НИКОГДА не наследуются.Так что нет никакого смысла в объявлении его окончательным.

6 голосов
/ 28 февраля 2012

Final : потому что вы все равно не можете переписать / расширить конструктор.Вы можете расширить класс (чтобы не сделать его окончательным) или перезаписать метод (чтобы не сделать его окончательным), но для конструкторов ничего подобного нет.

Статический Если вы посмотрите на выполнение, конструктор не является статическим (он может получить доступ к полям экземпляра), если вы посмотрите на сторону вызывающего, он (своего рода) статичен (вы вызываете его без экземпляра. Трудно представить, что конструктор являетсяполностью статический или не статичный, и без семантического разделения между этими двумя вещами не имеет смысла различать их с помощью модификатора.

Abstract : Аннотация имеет смысл только при наличииперезапись / расширение, поэтому применяется тот же аргумент, что и для 'final'

3 голосов
/ 08 января 2016
  1. Конструкторы НЕ являются обычными методами. (применяются разные правила)
  2. Кроме того, конструкторы НИКОГДА не наследуются. Так что нет никакого смысла в объявлении его окончательным. Конструкторы НИКОГДА не могут быть объявлены окончательными. ВАШ компилятор всегда выдаст ошибку типа "модификатор final не разрешен"
  3. Проверьте раздел 8.8.3 JLS (документы JLS и API должны быть вашими основными источниками информации).
2 голосов
/ 28 февраля 2012

JLS раздел 8 упоминает об этом.

Конструкторы (§8.8) похожи на методы , но не могут быть вызваны напрямую вызовом метода;они используются для инициализации новых экземпляров классов.Как и методы, они могут быть перегружены (§8.8.8).

Но, скажем, конструкторы не являются обычными методами.Их нельзя сравнивать как таковые.

1 голос
/ 08 марта 2014

почему конструктор не может быть статическим и окончательным, хорошо определены в ответах выше.

Аннотация: «Аннотация» означает отсутствие реализации.и это может быть реализовано только через наследование.Поэтому, когда мы расширяем некоторый класс, все члены родительского класса наследуются в подклассе (дочернем классе), кроме «Конструктора».Итак, предположим, вам как-то удается объявить конструктор "Abstract", чем как вы можете дать его реализацию в подклассе, когда конструктор не наследуется в дочернем классе?

, поэтому конструктор не может быть абстрактным.

0 голосов
/ 31 мая 2015

давайте посмотрим первым финальная публика K () {

* над модификатором final is restrict, потому что если он final, то возникает ситуация, когда в каком-то другом классе или в том же классе мы только переопределим его, так что это не произойдет здесь, приблизительно, не final например:

we want public void(int i,String name){
//this code not allowed

Пусть static ,, static itz все об уровне класса, но мы создаем объектный конструктор, используя ключевое слово 'new', так ,,,,,, thatsall

abstract itz худший из здесь не at 'потому что не имеет никакого абстрактного метода или любого объявленного метода

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