JavaRush/Java блог/Random/Ключевое слово this {в примерах}
Автор
Jesse Haniel
Главный архитектор программного обеспечения в Tribunal de Justiça da Paraíba

Ключевое слово this {в примерах}

Статья из группы Random
участников
На JavaRush студентов буквально с первых лекций знакомят с ключевым словом this. И со временем становится понятно, что все же оно означает. Но многие, обернувшись назад, наверное, честно себе скажут, что долго не могли осознать дзен этого ключевого слова. В статье приоткрываем завесу тайн применения ключевика this для тех, кто до сих пор в него не может… Welcome! Если коротко: this это ссылка на текущий объект, тот, у которого вызвали метод или конструктор. Чаще всего this нужен в двух случаях: чтобы различить поле класса и одноименный параметр (this.name = name) и чтобы вызвать один конструктор класса из другого (this(...)).

Кратко

  • this это ссылка на текущий объект, тот, у которого вызван метод или конструктор.
  • Первое применение: различить поле класса и одноименный параметр, например this.name = name.
  • Второе применение: вызвать один конструктор класса из другого через this(...).
  • Вызов this(...) должен быть первой строкой в конструкторе.
  • this неявно передается во все нестатические методы, поэтому в static-методах его использовать нельзя.
  • Кроме этого, this можно передавать как аргумент и возвращать из метода (return this) для цепочек вызовов.
Если вы возьмете справочник Шилдта по Java, то на 171 странице вы прочитаете о том, что ключевое слово this требуется для того, чтобы метод мог сослаться на вызвавший его объект. На этом, собственно можно было бы и закончить. Но нам нужна конкретика. Ключевое слово this в Java на примерахКак правило, применять this нужно в двух случаях:
  1. Когда у переменной экземпляра класса и переменной метода/конструктора одинаковые имена;
  2. Когда нужно вызвать конструктор одного типа (например, конструктор по умолчанию или параметризированный) из другого. Это еще называется явным вызовом конструктора.
Вот и все, на самом деле не так много, всего два случая, когда применяется это страшное ключевое слово. Теперь давайте рассмотрим эти две ситуации на примерах.

Пример первый: у переменной экземпляра и метода одинаковые имена

Допустим, у нас есть класс Human, для которого определено поле «имя»: Класс Human с полем nameДавайте для переменной name создадим сеттер (setter вполне рабочий и никакого подвоха здесь нет): Сеттер setName с параметром newNameОбратите внимание, что в метод (сеттер) setName мы передаем переменную String newName. Мы ввели новую переменную и (в общем-то) могли назвать ее как угодно ведь она будет видна только в пределах {фигурных скобок} метода setName. Обратите внимание, что в сеттере есть одна строка:
name = newName;
То есть по факту мы ввели новую переменную newName и присвоили ее уже существующей в классе переменной name. Многим программистам казалось это странным: вводить переменную с новым именем, если в итоге речь идет об одном и том же. Об имени в классе Human. Поэтому, разработчики языка задумались о том, чтобы удобно сделать использование одного имени переменной. Другими словами, зачем иметь два имени для переменной, обозначающей одно и то же. То есть хотелось бы сделать как-то так: Сеттер, где параметр назван так же, как поле класса (name)Но в этом случае возникает проблема. У нас теперь две переменные, которые называются одинаково. Один String name принадлежит классу Human, а другой String name его методу setName. Поэтому Java-машина не знает, какую переменную вы имеете в виду, когда пишете строку в сеттере:
name = name;
Java берет самую близкую переменную name из метода setName:
Java выбирает ближайшую переменную name из метода, а не поле класса
и получается, что вы просто присваиваете значение переменной name из этого метода, ей же. Что конечно не имеет никакого смысла. Поэтому нужен был какой-то способ, чтобы отличить переменную name из класса Human, от переменной name из метода setName.Для решения этой проблемы и было введено ключевое слово this, которое в данном случае укажет, что нужно вызывать переменную не метода, а класса Human:
this.name указывает на поле класса и решает конфликт имен
То есть this сошлется на вызвавший объект, как было сказано в начале статьи. В результате чего имя человека через сеттер setName будет установлено создаваемому объекту. Ниже приведен программный код без использования ключевого слова this. В коде создается объект класса Human и присваивается ему имя:
Пример кода без ключевого слова this
А ниже программный код с ключевым словом this:
public class Solution{
    public static void main(String[] args) {
        Human human1 = new Human();
        human1.setName("Volodya");
        human1.print();
    }
}
class Human{
    String name;
    public String getName() {
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    void print(){
        System.out.println(name);
    }
}
Таким образом, здесь this позволяет не вводить новые переменные для обозначения одного и того же, что позволяет сделать код менее «перегруженным» дополнительными переменными.

Пример второй: применение this для явного вызова конструктора

Вызов одного конструктора из другого может пригодиться тогда, когда у вас (как ни странно) несколько конструкторов и вам не хочется в новом конструкторе переписывать код инициализации, приведенный в конструкторе ранее. Запутал? Все не так страшно как кажется. Посмотрите на код ниже, в нем два конструктора класса Human:
class Human{
    int age;
    int weight;
    int height;

    Human(int age, int weight){
        this.age = age;
        this.weight = weight;
    }
    Human(int age, int weight, int height){
        //вы вызываете конструктор с двумя параметрами
        this(age, weight);
        //и добавляете недостающую переменную
        this.height = height;
    }
}
Здесь у нас сначала приводится конструктор с двумя параметрами, который принимает int age и int weight. Допустим, мы написали в нем две строчки кода:
this.age = age;
this.weight = weight;
а потом решили добавить еще один конструктор, с тремя параметрами, который помимо возраста и веса принимает еще и рост. В новом конструкторе вы бы могли написать так:
this.age = age;
this.weight = weight;
this.height = height;
Но вместо того, чтобы повторять уже написанный ранее код в этом конструкторе, вы можете с помощью ключевого слова this явно вызвать конструктор с двумя параметрами:
this(age, weight);
// и дописываете недостающую переменную:
this.height = height;
Таким образом, вы как-бы говорите конструктору с тремя параметрами:
  • вызови this (этот) конструктор, который имеет два параметра.
  • и добавить недостающую переменную.
Вот и все =). Напоследок отметим, что ключевое слово this в Java используется только в составе методов либо конструкторов экземпляра класса. Но неявно ключевое слово this передается во все методы, кроме статических (поэтому this часто называют неявным параметром) и может быть использовано для обращения к объекту, вызвавшему метод. Бояться этого ключевого слова не нужно, потому что This не страшно.
Итоги: ключевое слово this в Java не страшно

Вопросы и ответы

Что делает ключевое слово this в Java? this это ссылка на текущий объект, тот, у которого вызвали метод или конструктор. Через this метод обращается к полям и методам своего объекта. Зачем нужен this, если имя поля и параметра совпадают? Чтобы различить их: this.name это поле объекта, а name это локальный параметр. Без this строка name = name просто присвоила бы параметр самому себе и не имела бы смысла. Как вызвать один конструктор из другого? Через вызов this(параметры) внутри конструктора. Такой вызов должен стоять первой строкой конструктора, иначе будет ошибка компиляции. Можно ли использовать this в статическом методе? Нет. this неявно передается только в нестатические методы, у которых есть объект. У static-метода объекта нет, поэтому this там недоступен. Какие еще есть применения this? Кроме разрешения конфликта имен и вызова конструктора, this можно передавать как аргумент в другой метод и возвращать из метода (return this) для цепочек вызовов, например в fluent-интерфейсах и билдерах. Нужно ли писать this перед каждым полем? Нет. this обязателен только при конфликте имен или для явного вызова конструктора и передачи объекта. В остальных случаях поле и так доступно по имени. Источник: Oracle Java Tutorials: Using the this Keyword.

Читайте также

Комментарии (95)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Senya
Уровень 17
6 апреля 2024, 12:50
this далеко не только в 2х случаях применяют. В 11 уровне 5й лекции другой случай. плюс еще можно встретить в таком исполнении
public class PasingThis {
    public static void main(String[] args) {
        new Person().eat(new Apple());
    }
}

class Person {
    public void eat(Apple apple) {
        Apple peeled = apple.getPeeled();
        System.out.println("Yummi");
    }
}

class Peeler {
    static Apple peel(Apple apple) {
        //снимаем кожуру
        return apple;
    }
}

class Apple {
    Apple getPeeled(){
        return Peeler.peel(this);
    }
}
Jack Hughes
Уровень 2
24 апреля 2025, 07:54
Так это тоже самое ключевое слово this требуется для того, чтобы метод мог сослаться на вызвавший его объект. этот this как раз таки ссылается на вызвавший его объект Яблоко getPeelled () { return Peeler.peel (яблоко)
Алексей Барищук
Уровень 45
Expert
5 января 2024, 14:34
public boolean equals(Object obj)
{
   if (this == obj)
    return true;
https://javarush.com/quests/lectures/questsyntaxpro.level10.lecture04 тут походу третий случай...
Бромгексин
Уровень 38
20 февраля 2024, 12:45
вот ис this???
Oraz Janov Backend Developer
11 апреля 2023, 08:20
THIS is Хорошо
RomaSky QA Automation Engineer
17 января 2023, 04:07
Но неявно ключевое слово this передается во все методы...... .....и может быть использовано для обращения к объекту, вызвавшему метод. А можно пример чтобы "явно" понять данный вывод :)
31 января 2023, 20:39
В Java все методы хранятся в классах (Думаю это и так понятно). Обратиться к this можно только внутри НЕ статического метода => создаем экземпляр и вызываем метод, в котором мы можем обратиться к конкретному объекту и его полям через this.
Alexander Kurkin
Уровень 2
31 августа 2022, 07:35
А в многопоточности когда мы по this синхронизируем блок кода syncronized(this)?
fedyaka
Уровень 36
27 октября 2022, 10:36
на сколько я знаю, что если мы синхронизируем блок кода по syncronized(this), то поток который займёт этот блок кода заблокирует мьютекс этого объекта и с ним не смогут взаимодействовать другие потоки, пока этот поток не выйдет из syncronized блока. А если syncronized(какая то перемернная объект), то он заблокирует мьютекс уже объекта этой переменной и другие потоки просто не смогут обратиться к этой переменной, но смогут продолжить работу с другими переменными.
Стас
Уровень 28
26 августа 2022, 05:15
Потому что
this
не страшно.
Михаил
Уровень 20
19 июля 2022, 09:04
Надо допjлнить статью вот таким примером вызова this
public class Example {

    public static void main(String[] args) {
        Cat cat = new Cat("Вася");
        Cat cat1 = new Cat("Петя");
        Cat cat2 = new Cat("!-Доминатор-!");

        cat.sayName();
        cat1.sayName();
        cat2.sayName();
    }



    private static class Cat{
        String name;

        public Cat(String name){
            this.name = name;
        }

        public void sayName(){
            printName(this);
        }
    }

    private static void printName(Cat cat){
        System.out.println(cat.name);
    }
}
пример стащил с раздела помощь
Иван Аканов Backend Developer
15 июня 2023, 05:59
Спасибо bro! Искал как раз это применение!
Елена
Уровень 41
20 апреля 2022, 13:14
в каких случаях применяется второй способ this?
Qunjaviqunari в Java Inquisition
17 июля 2022, 11:17
"Вызов одного конструктора из другого может пригодиться тогда, когда у вас несколько конструкторов и вам не хочется в новом конструкторе переписывать код инициализации, приведенный в конструкторе ранее."
Peter
Уровень 2
1 апреля 2022, 21:42
Впринципе хорошо, но можно было ещё добавить про затенение переменных, если такая же переменная создаётся в методе. А так же добавить, что со статическими переменными this не работает и тогда чтобы вывести статическую переменную изза затенения новой, нужно обращаться к переменной чере Класс.
human.name
Anonymous #2981142
Уровень 4
29 января 2022, 17:05
Шикарно