1. Статические методы
Кроме статических переменных, в классах могут быть и статические методы.
Обычные методы привязаны к объектам (экземплярам) класса и могут обращаться к обычным-переменным класса (а также к статическим переменным и методам). Статические же методы привязаны к статическому объекту класса и могут обращаться только к статическим переменным и/или другим статическим методам класса.
Чтобы вызвать обычный метод у класса, сначала нужно создать объект этого класса, а только потом вызвать метод у объекта. Вызвать обычный метод не у объекта, а у класса нельзя.
Пример:
Вызвать нестатический метод у класса нельзя! |
---|
|
А чтобы вызвать статический метод, достаточно чтобы просто существовал статический объект класса (который всегда существует после загрузки класса в память). Именно поэтому метод main() — статический. Он привязан к статическому объекту класса, для его вызова не нужно создавать никакие объекты.
Чтобы объявить метод статическим, нужно перед заголовком метода написать ключевое слово static. Общий вид этой конструкции такой:
static тип имя(параметры)
{
код метода
}
Примеры:
Код | Примечание |
---|---|
|
Метод main вызывается Java-машиной командой вида: Solution.main() ;
Статический метод test() вызывается в статическом методе main() .
|
Чтобы вызвать статический метод из другого класса, нужно указать имя класса перед именем статического метода. Общий вид этой конструкции такой:
Тип имя = ИмяКласса.имяМетода(параметры)
Примеры:
Код | Статический метод |
---|---|
|
|
|
|
|
|
2. Статические vs Обычные методы
Чем же отличаются статические методы от обычных?
Обычный метод имеет привязку к объекту — экземпляру класса, статический же метод такой привязки не имеет. Обычный метод может обращаться к переменным в своем экземпляре класса, статический — нет: у него просто нет никакого экземпляра класса, связанного с ним.
Отличия двух типов методов можно выразить в таблице:
Способность | Обычный метод | Статический метод |
---|---|---|
Есть связь с экземпляром класса | Да | Нет |
Может вызывать обычные методы класса | Да | Нет |
Может вызывать статические методы класса | Да | Да |
Может обращаться к обычным переменным класса | Да | Нет |
Может обращаться к статическим переменным класса | Да | Да |
Может быть вызван у объекта | Да | Да |
Может быть вызван у класса | Нет | Да |
Зачем такие методы нужны, если они так сильно ограничены? Все дело в том, что у такого подхода тоже есть свои преимущества.
Во-первых, чтобы обратиться к статическим методам и переменным, не надо передавать никакую ссылку на объект.
Во-вторых, иногда бывает нужно, чтобы переменная была в единственном экземпляре. Как, например, переменная System.out
(статическая переменная out класса System).
И, в-третьих, иногда нужно вызвать метод еще до того, как будет возможность создавать какие-то объекты. Например, вызов метода main(), с которого начинается выполнение программы: его вызывает Java-машина до создания экземпляра класса.
Есть связь с экземпляром класса
При вызове обычного метода в него передается скрытый параметр — объект, у которого его вызывали. Этот параметр имеет имя this
. Именно этот скрытый параметр — ссылка на объект, у которого вызвали метод — и отличает обычные методы от статических.
У статических методов такого скрытого параметра нет, поэтому внутри статических методов нельзя пользоваться ключевым словом this
, и из статического метода нельзя вызвать нестатический: ссылку на экземпляр класса попросту неоткуда взять.
Может вызывать обычные методы класса
В обычном методе класса всегда есть скрытый параметр — this
— ссылка на объект класса, у которого был вызван метод. Каждый раз, когда вы вызываете обычный метод внутри другого обычного метода, для этого вызова используется скрытый параметр this
. Пример
Код | Как оно работает |
---|---|
|
|
Именно поэтому нельзя вызвать обычный метод из статического. Внутри статического метода просто нет скрытой переменной с именем this
.
Ну или представьте другой случай: в программе еще не создан ни один объект нашего класса. Статический метод класса можно вызвать? Да. А сможет этот статический метод вызвать обычный метод?
И у какого объекта он его вызовет? Ведь еще не существует ни одного экземпляра нашего класса!
Может вызывать статические методы класса
Статические методы можно вызывать откуда угодно — из любого места программы. А значит, их можно вызывать и из статических методов, и из обычных. Никаких ограничений тут нет.
Может обращаться к обычным переменным класса
Из обычного метода можно обращаться к обычным переменным класса, т.к. при этом произойдет обращение к переменным экземпляра класса, который легко получить из скрытого параметра this
.
Статический метод не знает, из какого экземпляра класса ему брать значения обычных переменных. У нас вообще легко может быть ситуация, когда статический метод вызван, а ни одного экземпляра класса еще создано в программе не было.
Поэтому статические методы не могут обращаться к обычным переменным класса.
Статический метод вызывает обычный метод, вот только у какого объекта он должен вызваться?
Неизвестно! Поэтому и нельзя вызывать обычный метод из статического, не указывая ссылку на объект!
Может обращаться к статическим переменным класса
Ситуация с обращением к статическим переменным такая же, как и с обращениями к статическим методам. К статическим переменным можно обращаться из любого места в программе. А значит, можно обращаться из статических и обычных методов.
Может быть вызван у объекта
И статические, и обычные методы можно вызывать у объекта. Обычный метод можно, потому что только у объекта его вызвать и можно. Статический метод тоже можно вызывать у объекта: при этом компилятор сам определит тип переменной и вызовет статический метод по ее типу:
Код | Как его видит компилятор |
---|---|
|
|
|
|
|
|
Может быть вызван у класса
У класса можно вызвать только статический метод, для вызова обычного метода нужна ссылка на экземпляр класса. Поэтому нельзя вызвать обычный метод конструкцией вида ИмяКласса.имяМетода(параметры)
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ