Ключевое слово Static в Java — статические переменные, методы, классы и блоки.
Static — это ключевое слово в Java, которое можно применять к переменным, методам, классам и блокам. В этом посте представлен обзор поведения переменных, методов, классов и блоков кода в Java, когда к ним применяется ключевое слово static. Давайте подробно обсудим каждый из них:
1. Статические переменные
- Статические переменные также известны как переменные класса.
- Когда статический ключевое слово применяется к переменной, это означает, что переменная принадлежит классу, а не экземпляру класса.
- В памяти есть только одна копия статической переменной, которая используется всеми экземплярами класса.
- Статические переменные инициализируются перед любой из переменных экземпляра.
- Статические переменные можно использовать, когда какое-то значение необходимо разделить между всеми объектами класса. Чтобы гарантировать, что значение никогда не изменится после его инициализации, объявите статическую переменную как final.
- Доступ к статической переменной можно получить напрямую, используя имя класса, без создания экземпляра класса, в котором они определены. Используйте обозначение >.> для доступа к статической переменной. В пределах одного класса к ним можно получить прямой доступ.
- Стандартный выходной поток System.out отличный пример статической переменной в Java. Здесь out объявляется статическим в System учебный класс.
Рассмотрим следующий код со статической переменной i определено в классе A . К нему можно получить прямой доступ по имени i внутри класса A и с A.i вне класса A .
10 заметок о модификаторе Static в Java
Модификатор static в Java напрямую связан с классом. Если поле статично, значит оно принадлежит классу, если метод статичный — аналогично: он принадлежит классу. Исходя из этого, можно обращаться к статическому методу или полю, используя имя класса. Например, если поле count статично в классе Counter, значит, вы можете обратиться к переменной запросом вида: Counter.count. Прежде чем приступить к заметкам, давайте вспомним (а может быть, узнаем), что такое static и что может быть статическим в Java. Static — модификатор, применяемый к полю, блоку, методу или внутреннему классу. Данный модификатор указывает на привязку субъекта к текущему классу.
Статические поля
При обозначении переменной уровня класса мы указываем на то, что это значение относится к классу. Если этого не делать, то значение переменной будет привязываться к объекту, созданному по этому классу. Что это значит? А то, что если переменная не статическая, то у каждого нового объекта данного класса будет своё значение этой переменной, меняя которое мы меняем его исключительно в одном объекте: Например, у нас есть класс Car с нестатической переменной:
Car orangeCar = new Car(); orangeCar.km = 100; Car blueCar = new Car(); blueCar.km = 85; System.out.println("Orange car - " + orangeCar.km); System.out.println("Blue car - " + blueCar.km);
Orange car - 100 Blue car - 85
Как видим, у каждого объекта своя переменная, изменение которой происходит только для этого объекта. Ну а если у нас переменная статическая, то это глобальное значение — одно для всех: Теперь мы имеем Car со статической переменной:
Orange car - 85 Blue car - 85
Ведь переменная у нас одна на всех, и каждый раз мы меняем именно ее. К статическим переменным, как правило обращаются не по ссылке на объект — orangeCar.km, а по имени класса — Car.km
Статический блок
Есть два блока инициализации — обычный и статический. Блок предназначен для инициализации внутренних переменных. Если блок обычный, то им инициализируют внутренние переменные объекта, если же статический, соответственно, им задают статические переменные (то есть переменные класса). Пример класса со статическим блоком инициализации:
Статический метод
Статические методы отличаются от обычных тем, что они также привязаны к классу, а не к объекту. Важным свойством статического метода является то, что он может обратиться только к статическим переменным/методам. В качестве примера давайте рассмотрим класс, который у нас будет неким счётчиком, ведущим учет вызовов метода:
Counter.invokeCounter(); Counter.invokeCounter(); Counter.invokeCounter();
Текущее значение счётчика - 1 Текущее значение счётчика - 2 Текущее значение счётчика - 3
Статический класс в Java
Статическим классом может быть только внутренний класс. Опять же, этот класс привязан к внешнему классу, и если внешний наследуется другим классом, то этот не будет наследован. При этом данный класс можно наследовать, как и он может наследоваться от любого другого класса и имплементировать интерфейс. По сути статический вложенный класс ничем не отличается от любого другого внутреннего класса за исключением того, что его объект не содержит ссылку на создавший его объект внешнего класса. Тем не менее, благодаря этому статический класс наиболее похож на обычный не вложенный, ведь единственное различие состоит в том, что он упакован в другой класс. В некоторых случаях для нас это преимущество, так как с него у нас есть доступ к приватным статическим переменным внешнего класса. Пример вложенного статического класса:
Vehicle.Car car = new Vehicle.Car(); car.km = 90;
Для использования статических методов/переменных/класса нам не нужно создавать объект данного класса. Конечно, следует учитывать модификаторы доступа. Например, поля private доступны только внутри класса, в котором они объявлены. Поля protected доступны всем классам внутри пакета (package), а также всем классам-наследникам вне пакета. Для более подробной информации ознакомьтесь со статьей “private vs protected vs public”. Предположим, существует статический метод increment() в классе Counter , задачей которого является инкрементирование счётчика count . Для вызова данного метода можно использовать обращение вида Counter.increment() . Нет необходимости создавать экземпляр класса Counter для доступа к статическому полю или методу. Это фундаментальное отличие между статическими и НЕ статическими объектами (членами класса). Еще раз напомню, что статические члены класса напрямую принадлежат классу, а не его экземпляру. То есть, значение статической переменной count будет одинаковое для всех объектов типа Counter . Далее в этой статье мы рассмотрим основополагающие аспекты применения модификатора static в Java, а также некоторые особенности, которые помогут понять ключевые концепции программирования.
Что должен знать каждый программист о модификаторе Static в Java
- Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка:
class Vehicle < public static void kmToMiles(int km)< System.out.println("Внутри родительского класса/статического метода"); >> class Car extends Vehicle < public static void kmToMiles(int km)< System.out.println("Внутри дочернего класса/статического метода "); >> public class Demo< public static void main(String args[])< Vehicle v = new Car(); v.kmToMiles(10); >>
Chapter 8. Classes
A class declaration defines a new class and describes how it is implemented (§8.1).
A top level class (§7.6) is a class declared directly in a compilation unit.
A nested class is any class whose declaration occurs within the body of another class or interface declaration. A nested class may be a member class (§8.5, §9.5), a local class (§14.3), or an anonymous class (§15.9.5).
Some kinds of nested class are an inner class (§8.1.3), which is a class that can refer to enclosing class instances, local variables, and type variables.
An enum class (§8.9) is a class declared with abbreviated syntax that defines a small set of named class instances.
A record class (§8.10) is a class declared with abbreviated syntax that defines a simple aggregate of values.
This chapter discusses the common semantics of all classes. Details that are specific to particular kinds of classes are discussed in the sections dedicated to these constructs.
A class may be declared abstract (§8.1.1.1) and must be declared abstract if it is incompletely implemented; such a class cannot be instantiated, but can be extended by subclasses. A class may be declared final (§8.1.1.2), in which case it cannot have subclasses. If a class is declared public , then it can be referred to from code in any package of its module and potentially from code in other modules. Each class except Object is an extension of (that is, a subclass of) a single existing class (§8.1.4) and may implement interfaces (§8.1.5). Classes may be generic (§8.1.2), that is, they may declare type variables whose bindings may differ among different instances of the class.
Class declarations may be decorated with annotations (§9.7) just like any other kind of declaration.
The body of a class declares members (fields, methods, classes, and interfaces), instance and static initializers, and constructors (§8.1.6). The scope (§6.3) of a member (§8.2) is the entire body of the declaration of the class to which the member belongs. Field, method, member class, member interface, and constructor declarations may include the access modifiers public , protected , or private (§6.6). The members of a class include both declared and inherited members (§8.2). Newly declared fields can hide fields declared in a superclass or superinterface. Newly declared member classes and member interfaces can hide member classes and member interfaces declared in a superclass or superinterface. Newly declared methods can hide, implement, or override methods declared in a superclass or superinterface.
Field declarations (§8.3) describe class variables, which are incarnated once, and instance variables, which are freshly incarnated for each instance of the class. A field may be declared final (§8.3.1.2), in which case it can be assigned to only once. Any field declaration may include an initializer.
Member class declarations (§8.5) describe nested classes that are members of the surrounding class. Member classes may be static , in which case they have no access to the instance variables of the surrounding class; or they may be inner classes.
Member interface declarations (§8.5) describe nested interfaces that are members of the surrounding class.
Method declarations (§8.4) describe code that may be invoked by method invocation expressions (§15.12). A class method is invoked relative to the class; an instance method is invoked with respect to some particular object that is an instance of a class. A method whose declaration does not indicate how it is implemented must be declared abstract . A method may be declared final (§8.4.3.3), in which case it cannot be hidden or overridden. A method may be implemented by platform-dependent native code (§8.4.3.4). A synchronized method (§8.4.3.6) automatically locks an object before executing its body and automatically unlocks the object on return, as if by use of a synchronized statement (§14.19), thus allowing its activities to be synchronized with those of other threads (§17 (Threads and Locks)).
Method names may be overloaded (§8.4.9).
Instance initializers (§8.6) are blocks of executable code that may be used to help initialize an instance when it is created (§15.9).
Static initializers (§8.7) are blocks of executable code that may be used to help initialize a class.
Constructors (§8.8) are similar to methods, but cannot be invoked directly by a method call; they are used to initialize new class instances. Like methods, they may be overloaded (§8.8.8).