Оговорка: 14:03
static level
method
field
.
Перед просмотром лекции желательно освежить в памяти знания про методы: что такое методы, как их создавать и как их вызывать, и про пакеты.
инстанс (instance) — один экземпляр (объект), созданный на основе класса.
instantiation (создание объекта) — процесс создания объекта на основе класса. Пример: new Object()
; — где-то в памяти создан один экземпляр класса Object
.
Уровни методов
Методы бывают двух уровней — уровня инстанс (не static) и уровня класса (static) . Метод уровня инстанс — без ключевого слова static, если же слово static присутствует - метод уровня класса.
Поля, как и методы, тоже имеют уровень класса и объекта. Поля с модификатором
static
видны всем объектам (инстансам) класса, а без этого модификатора — видны только внутри отдельно взятого инстанса.
Пример instance level methods:
class Game {
int levels = 3;
public void printGameName() {
System.out.println("Star Wars!");
}
public void printLevelCount() {
System.out.printf("Levels count %d", this.levels);
}
}
- Первый метод
printGameName()
— выводит на экран название игры. - Второй метод
printLevelCount()
— выводит на экран количество уровней.
Ссылка this
не обязательна перед полем levels
, поскольку метод нестатический и он привязан к конкретному экземпляру класса. Компилятор сам подставит туда this
.
Эту ссылку, this
, каждый нестатический метод, хранит в своем фрейме (помним, что фреймы методов находятся в стеке).
Чтобы вызывать нестатические методы — нужен конкретный инстанс. Сначала создаем инстанс класса, и после этого только вызываем.
class Main {
public static void main(String... args) {
Game game = new Game(); // создали объект
game.printGameName(); // вызвали метод
}
}
Нужен ли this
при вызове этого метода? (Указатель на текущий инстанс в оперативной памяти).
В методе printGameName()
не нужен, поскольку он привязан к своему объекту.
Добавим статический метод и поле:
class Game {
static int someCounter = 0;
int levels = 3;
public static void setSomething() {
someCounter++;
}
public void printGameName() {
System.out.println("Star Wars!");
}
public void printLevelCount() {
System.out.printf("Levels count %d", this.levels);
}
}
При создании фрейма в стеке, для метода уровня класса, в фрейме не будет ссылки this
. Такие методы не имеют доступа к полям инстанса. Для вызова такого метода не нужен инстанс, так как он не использует поля инстанса. Вызвать такой метод можно из под имени класса.
Вот так:
public class Main {
public static void main(String... args) {
Game.setSomething(); // обращаемся к статическому методу класса
}
}
Но что делать, если нам нужен один статический метод, который сможет делать изменения в экземплярах своего класса или получать доступ к нестатическим полям этих экземпляров? — Нужно передать ему экземпляр, с которым должен провзаимодействовать этот статический метод.
Переделаем наш Game
так:
public class Game {
static int someCounter = 0;
int levels = 3;
public static void setSomething(Game someInstance) {
someCounter++;
someInstance.levels++; // теперь статический метод получает доступ к нестатическому полю, через объект
}
public void printGameName() {
System.out.println("Star Wars!");
}
public void printLevelCount() {
System.out.printf("Levels count %d", this.levels);
}
}
Использовать это можно так:
public class Main {
public static void main(String... args) {
Game game = new Game();
Game.setSomething(game);
}
}
Статическое импортирование (дополнение к "Модуль 2. Урок 4. Пакеты в Java.")
Статический импорт позволяет использовать статические методы и поля импортируемых классов без имен этих классов.
Разберем пример:
package com;
class Foo {
public static void main(String[] args) {
double result = Math.sqrt(5); // 2.23606797749979
System.out.println(result);
}
}
Этот класс использует статический метод и поле: sqrt
и out
(у статического поля out
мы просто вызвали метод println
). Если проследить их пакетную иерархию — обнаружится, что Math
и System
находятся в java.lang
, то есть они импортированы автоматически.
Но мы можем использовать эти статические методы и поля прямо, без указания имени их классов.
Для статического импорта, сюрприз-сюрприз, используется ключевое слово static
перед адресом и звездочки .*
после имени класса.
Пример:
package com;
import static java.lang.System.*;
import static java.lang.Math.*;
class Foo {
public static void main(String[] args) {
double result = sqrt(10); // 3.1622776601683795
out.println(result);
}
}
Не смотря на то, что java.lang
и так импортируется автоматически, для статического импорта — все равно пришлось прописать импорты необходимых классов.
Обратите внимание, что при импортировании классов — точки в конце не нужно ставить!
Дальше создание классов на реальном проекте "Крестики-нолики".
Полезные ссылки
- Static методы / static переменные
- Использование ключевого слова this

Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»