2016-02-19 4 views
56

Как я понимаю:Почему статические имеют разные значения в зависимости от контекста?

  • Статический класс применяется только для вложенных классов, и это означает, что вложенный класс не имеет ссылок на внешний класс.

  • Статическое поле похоже на глобальную переменную, в которой имеется только один экземпляр, и он разделяется другими членами того же класса.

  • Статический метод означает, что его можно вызвать, даже если объект еще не был создан.

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

+0

В любом случае не ставьте класс статического класса/поле/метод как стандартную номенклатуру ООП. Например, в python вы вызываете статический метод java методом класса, и существуют статические методы, которые являются другими. Поскольку ответ говорит * в java *, статический означает, что это что-то *, связанное с классом *, но не с его экземплярами. – Bakuriu

+1

Вы не хотите вводить * слишком много * ключевых слов на язык. Отбросьте проблемы пионеров (каждое ключевое слово делает исполняемый файл компилятора более крупным, а компиляция медленнее), каждое ключевое слово означает, что для пользователя, вероятно, полезный идентификатор. (Точка в случае, я работаю с языком, специфичным для домена, где 'input' является зарезервированным ключевым словом. * Это * боль, говорю вам.) Итак, когда * подобные * вещи должны быть достигнуты в * разных * контекстах , повторное использование ключевого слова является допустимым вариантом. – DevSolar

+1

С разумной точки зрения, все они действительно делают одно и то же: возьмите вещь и измените ее область от экземпляра к классу. C и C++, где 'static' действительно перегружен. – Kevin

ответ

70

Все ваши примеры верны, однако все они имеют общую функцию. Слово «статическое» означает, что необязательный экземпляр не требуется.

  • Только статический внутренний класс может существовать без прилагаемого экземпляра. Например, если у вас есть класс Foo и нестатический внутренний класс Bar, то вы не можете создать экземпляр Bar вне экземпляра Foo.

  • Статический метод означает, что вам не нужен экземпляр класса для вызова метода. Вы можете позвонить String.format без фактического примера String, например.

  • Статическое поле будет существовать даже без экземпляра класса. Если ваш класс Foo имеет поле counter, которое является статическим, вы можете получить к нему доступ, не создавая экземпляра класса Foo.

Рассмотрите, как поясняющий момент, что интерфейс может иметь статические классы, статические поля и статические методы. Однако он не может иметь нестатистическую версию любой из этих вещей (игнорируя методы по умолчанию, которые являются своего рода ad-hoc'd в концепции). Это связано с тем, что вы никогда не сможете создать экземпляр интерфейса, поэтому никогда не может быть закрывающего экземпляра.

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

Один последний византийский пункт. Если вы выполняете статический импорт (import static pack.age.Foo.*), вы сможете делать неквалифицированные ссылки на любые статические элементы в классе (включая интерфейсы, аннотации и перечисления независимо от того, являются ли они избыточно помечены как статические).

+1

s/переменная/класс/в третьей точке маркировки? – immibis

+0

@immibis спасибо – Pace

6

Все упомянутые применения статики имеют некоторую общность, как я ее вижу - во всех случаях они означают, что метод class/field/меньше привязан к экземпляру класса, чем это было бы без статичности. Конечно, эквивалентность между статическими полями и статическими методами в частности должна быть ясной: это способ объявить поля и методы singleton (per-classloader), которые работают с этими полями, аналогично глобальным объектам на других языках.

Возможно, тогда использование статики для вложенных классов не так очевидно, в том же духе, но оно разделяет аспект, который вам не нужен экземпляр содержащего класса для использования этой конструкции.

Таким образом, я не вижу в них особого противоречия.

Один из ответов на более общий вопрос о том, почему ключевые слова повторно используются для явно разных целей на языке программирования, так это то, что часто появляются функции с развитием языка, но трудно добавить новые ключевые слова, поскольку часто нарушают существующие программы который мог использовать это как идентификатор. Java, например, фактически резервирует ключевое слово const, даже если оно не используется на языке, возможно, для будущего расширения!

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

6

Java Tutorial says

Как и с методами и переменными класса, статический вложенный класс связан с его внешним классом. И как статические методы класса, статический вложенный класс не может ссылаться непосредственно на переменные экземпляра или методы , определенные в его классе-оболочке: он может использовать их только через ссылку на объект.

В основном «статический» означает, что сущность, помеченная им, отделена от экземпляров класса. У статического метода нет связанного с ним экземпляра. Статическое поле разделяется между всеми экземплярами (по существу, существует в классе, а не в экземпляре).
статические вложенные классы развелись с окружающим экземпляром. Вы правы, что это немного запутывает, потому что у вас может быть экземпляр статического вложенного класса с нестатическими методами и полями внутри него.
Придумайте слова статического, как говорят: «Я объявляя объект, поле, метод или внутренний класс, который собирается не иметь никакого отношения к ограждающему экземпляру»

19

Почему статические есть разные значения в зависимости от контекста? Почему не были использованы разные ключевые слова?

На самом деле это не имеет разных значений.

Вы можете взять static ключевое слово, чтобы указать следующее, где он может встречаться:

«без учета или отношения к какой-либо конкретном случае»

  • статическое поле один который принадлежит классу, а не любому конкретному экземпляру.

  • Статический метод определен в классе и не имеет понятия о this. Такой метод не может обращаться к никаким полям экземпляра в каком-либо конкретном экземпляре, кроме случаев, когда экземпляр передается ему.

  • Статический класс-член является вложенным классом, который не имеет понятия его охватывающего класса и не имеет отношения к какому-либо конкретному экземпляру его охватывающего класса, если такой экземпляр ему не передан (например, аргумент его конструктору) ,

+1

Хотя общий смысл ответа правильный, я не могу согласиться на некоторые конкретные части. «Такой метод не может обращаться к полюм экземпляра в каком-либо конкретном экземпляре, кроме случаев, когда экземпляр передается ему как параметр». - нет, он может получить доступ к экземпляру, который он создает (классический завод), или к нему можно получить статическую переменную (классический синглтон). Тот же материал с вашей следующей маркерной точкой - «если такой экземпляр не передан в качестве параметра его конструктору». - да, или любым другим способом можно установить переменную, в том числе методы setter, DI, статические поля и т. д. – Ordous

+0

* «Нет, он может получить доступ к экземпляру, который он создает (классический завод) или одному из статической переменной» * .. другой способ сказать то же самое, я бы сказал. Созданный экземпляр не является экземпляром, который имеет ранее существовавшие отношения со статическим методом. Хотя я не буду не соглашаться с духом вашего опровержения, и я не скажу, что это противоречит любому из того, что было опубликовано. – scottb

+0

«Статическое поле - это объект, который принадлежит классу» - нет, он не относится к объекту Class. То же самое для методов. – immibis

16

С Core Java по Cay Horstmann:

Термин «статический» имеет любопытную историю. Сначала ключевое слово static было введено в C до , обозначая локальные переменные, которые не исчезают при выходе из блока. В этом контексте термин «статический» имеет смысл: переменная остается вокруг и все еще существует, когда блок снова вводится . Затем статичность получила второе значение в C, чтобы обозначить глобальные переменные и функции , к которым невозможно получить доступ из других файлов. Ключевое слово static было просто повторно использовано, чтобы избежать , введя новое ключевое слово. Наконец, C++ повторно использовал ключевое слово для третьей, не связанной, интерпретации - для обозначения переменных и функций, принадлежащих классу, но не к любому объекту класса . То же самое значение имеет ключевое слово в Java.

+1

Я не согласен с тем, что цитата говорит о «статическом» C и C++, имеющем несколько несвязанных интерпретаций. С одной стороны, у всех их есть то, что адрес памяти переменной или функции каким-то образом исправлен. Я думаю, что это хорошо соответствует значению Java. –

+0

@ ThomasPadron-McCarthy: Да, но второй смысл в C на самом деле не имеет никакого отношения к этому, поскольку адрес глобальной переменной или функции фиксируется независимо от «статического». –

9

Java наследует от C++ и C. На этих языках static имеет два дополнительных значения. Локальная переменная (область функций), квалифицированная как static, имеет значение, несколько напоминающее значение статического поля в классе. Однако Java не поддерживает этот контекст «статического». Квалификация переменной или функции как static в C или C++ в области файлов означает «Ssh! Не говорите компоновщику!». Java также не поддерживает это значение static.

На английском языке одно и то же слово может иметь несколько значений, в зависимости от контекста. Посмотрите любое общеупотребимое слово в словаре, и вы найдете несколько определений этого слова. Некоторые слова не только имеют множественные значения, но и имеют несколько частей речи. Например, «Счетчик» может быть существительным, глаголом, прилагательным или наречием, в зависимости от контекста. Другие слова могут иметь противоречивые значения, в зависимости от контекста. «Извинение» может означать «Мне очень жаль!» или это может означать: «Я не жалею!» Первым примером последнего является «Апология математика» Г. Х. Харди. В этом отношении английский совсем не уникален; то же самое относится к любому языку, который люди используют для общения друг с другом. Как люди, мы привыкли к словам, имеющим разные значения в зависимости от контекста.

Существует неразрывный конфликт между наличием слишком большого количества ключевых слов и слишком большого количества на компьютерном языке. Lisp, 4th и smalltalk - очень красивые языки с очень немногими, если есть, ключевыми словами. У них есть несколько специальных символов, например, открывать и закрывать круглые скобки в lisp. (Полное раскрытие: я запрограммировал на всех трех этих языках, и мне это понравилось.) Здесь есть проблема: Удачи, прочитав код, который вы сами написали через шесть месяцев после факта. Еще лучшая удача превратить этот код в кого-то другого. В результате на этих языках также имеется довольно ограниченное число сторонников. Другие языки переходят на верх и резервируют огромное количество слов как «ключевые слова». (Полное раскрытие: мне тоже пришлось программировать на этих языках, и я его ненавидел.)

Слишком мало или слишком много ключевых слов на компьютерном языке приводит к когнитивному диссонансу. У того же ключевого слова разные контексты в разных нет, потому что, как люди, мы довольно привыкли к этому.

Смежные вопросы