Почему статика имеет разные значения в зависимости от контекста?
Как я понимаю:
-
Статический класс применяется только к вложенным классам, а это означает, что вложенный класс не имеет ссылок на внешний класс.
-
Статическое поле похоже на глобальную переменную, поскольку в ней есть только один экземпляр, и он разделяется другими членами одного и того же класса.
-
Статический метод означает, что он может быть вызван, даже если объект еще не был создан.
Я читаю введение в курс Java и пытаюсь укрепить свои знания, а также пытаюсь понять, почему разные ключевые слова не использовались для обозначения разных значений.
Ответы
Ответ 1
Ваши примеры верны, однако все они имеют общую функцию. Слово static означает, что охватывающий экземпляр не требуется.
-
Только закрытый внутренний класс может существовать без вмещающего экземпляра. Например, если у вас есть класс Foo
и нестатический внутренний класс Bar
, вы не сможете создать экземпляр Bar
вне экземпляра Foo
.
-
Статический метод означает, что вам не нужен экземпляр класса для вызова метода. Вы можете вызвать String.format
без фактического экземпляра String
, например.
-
Статическое поле будет существовать даже без экземпляра класса. Если ваш класс Foo
имеет поле counter
, которое является статичным, вы можете получить к нему доступ, не создавая экземпляра класса Foo
.
Рассмотрим в качестве поясняющего момента, что интерфейс может иметь статические классы, статические поля и статические методы. Однако он не может иметь нестатистическую версию любой из этих вещей (игнорируя методы по умолчанию, которые являются своего рода ad-hoc'd в концепции). Это связано с тем, что вы никогда не сможете создать экземпляр интерфейса, поэтому никогда не может быть закрывающий экземпляр.
Вы также можете объявить внутренние интерфейсы, аннотации и перечисления статическими, хотя ключевое слово в этом случае полностью избыточно (например, похоже на объявление абстрактного метода интерфейса). Интерфейсы, аннотации и перечисления не имеют отношения к окружающему классу, чтобы начать с такого статического, что на самом деле не может этого уйти.
Последняя византийская точка. Если вы выполняете статический импорт (import static pack.age.Foo.*
), вы сможете делать неквалифицированные ссылки на любые статические элементы в классе (включая интерфейсы, аннотации и перечисления независимо от того, являются ли они избыточно помечены как статические).
Ответ 2
Почему статика имеет разные значения в зависимости от контекста? Зачем не были ли использованы разные ключевые слова?
На самом деле это не имеет разных значений.
Вы можете взять ключевое слово static
, чтобы указать следующее, где бы оно ни возникало:
"без учета или отношения к какому-либо конкретному экземпляру"
-
Статическое поле - это класс, который принадлежит классу, а не любому конкретному экземпляру.
-
Статический метод определен в классе и не имеет понятия this
. Такой метод не может обращаться к полю экземпляра в каком-либо конкретном экземпляре, кроме случаев, когда экземпляр передается ему.
-
Статический класс-член представляет собой вложенный класс, который не имеет понятия своего охватывающего класса и не имеет отношения к какому-либо конкретному экземпляру его охватывающего класса, если такой экземпляр не передан ему (например, аргумент его конструктору).
Ответ 3
От Core Java от Cay Horstmann:
Термин "статический" имеет любопытную историю. Сначала ключевое слово static было введено в C обозначают локальные переменные, которые не исчезают при выходе из блока. В этом контексте термин "статический" имеет смысл: переменная остается вокруг и все еще существует, когда блок введен еще раз. Затем статичность получила второе значение в C, чтобы обозначить глобальные переменные и функции к которым нельзя получить доступ из других файлов. Ключевое слово static было просто повторно использовано, чтобы избежать вводя новое ключевое слово. Наконец, С++ повторно использовал ключевое слово для третьего, несвязанного, интерпретация - для обозначения переменных и функций, принадлежащих классу, но не к каким-либо конкретный объект класса. То же самое значение имеет ключевое слово в Java.
Ответ 4
Java наследуется от С++ и C. В этих языках static
имеет два дополнительных значения. Локальная переменная (область функций), квалифицируемая как static
, имеет значение, несколько похожее на значение статического поля в классе. Однако Java не поддерживает этот контекст "статического". Квалификация переменной или функции как static
в C или С++ в области файлов означает "Ssh! Не говорите компоновщику!". Java также не поддерживает это значение static
.
В английском языке одно и то же слово может иметь несколько значений, в зависимости от контекста. Посмотрите любое общеупотребимое слово в словаре, и вы найдете несколько определений этого слова. Некоторые слова не только имеют множественные значения, но и имеют несколько частей речи. Например, "Счетчик" может быть существительным, глаголом, прилагательным или наречием, в зависимости от контекста. Другие слова могут иметь противоречивые значения, в зависимости от контекста. "Извинение" может означать "Мне очень жаль!" или это может означать: "Я не жалею!" Первым примером последнего является "Апология математики" Г. Х. Харди. В этом отношении английский совсем не уникален; то же самое относится к любому языку, который люди используют для общения друг с другом. Как люди, мы привыкли к словам, имеющим разные значения в зависимости от контекста.
Внутри есть конфликт между слишком большим количеством ключевых слов и слишком большим количеством на компьютерном языке. Lisp, четвертый и smalltalk - очень красивые языки с очень маленькими, если есть, ключевыми словами. Они имеют несколько специальных символов, например, открывают и закрывают круглые скобки в lisp. (Полное раскрытие: я запрограммировал на всех трех этих языках, и мне это понравилось.) Там проблема: удачи, прочитав код, который вы сами написали через шесть месяцев после факта. Еще лучшая удача превратить этот код в кого-то другого. В результате на этих языках также имеется довольно ограниченное число сторонников. Другие языки переходят на верх и резервируют огромное количество слов как "ключевые слова". (Полное раскрытие: я был вынужден программировать и на этих языках, и я ненавидел его.)
Слишком мало или слишком много ключевых слов на компьютерном языке приводит к когнитивному диссонансу. Наличие одного и того же ключевого слова в разных контекстах в разных случаях не так, потому что как люди мы привыкли к этому.
Ответ 5
Все упомянутые применения статики имеют некоторую общность, как я ее вижу - во всех случаях они означают, что метод class/field/меньше привязан к экземпляру класса, чем это было бы без статичности. Разумеется, эквивалентность статических полей и статических методов в частности должна быть ясной: это способ объявить поля и методы singleton (per-classloader), которые работают с этими полями, подобно глобальным объектам на других языках.
Возможно, тогда использование static для вложенных классов не так очевидно в одном и том же духе, но оно разделяет тот аспект, в котором вам не нужен экземпляр содержащего класса для использования этой конструкции.
Поэтому я не вижу в них особого противоречия.
Один из ответов на более общий вопрос о том, почему ключевые слова повторно используются для явно разных целей на языке программирования, заключается в том, что часто появляются функции с развитием языка, но трудно добавить новые ключевые слова, поскольку часто нарушают существующие программы, которые возможно, использовали это как идентификатор. Java, например, фактически резервирует ключевое слово const
, даже если оно не используется на языке, возможно, для будущего расширения!
Это нежелание добавлять новые ключевые слова часто приводит к перегрузке старых.
Ответ 6
Учебник по Java
Как и в методах и переменных класса, статический вложенный класс связанный с его внешним классом. И как методы статического класса, статический вложенный класс не может напрямую ссылаться на переменные экземпляра или методы, определенные в его охватывающем классе: он может использовать их только через ссылка на объект.
В основном "статический" означает, что сущность, помеченная им, отделена от экземпляров класса. У статического метода нет связанного с ним экземпляра. Статическое поле разделяется между всеми экземплярами (по существу, существует в классе, а не в экземпляре).
статические вложенные классы оторваны от вмещающего экземпляра. Вы правы, что это немного запутанно, потому что у вас может быть экземпляр статического вложенного класса с нестатическими методами и полями внутри него.
Подумайте о статическом слове: "Я объявляю сущность, поле, метод или внутренний класс, который не будет иметь отношения к охватывающему экземпляру"