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

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

Статья из группы Random
участников
На JavaRush студентов буквально с первых лекций знакомят с ключевым словом this. И со временем становится понятно, что все же оно означает. Но многие, обернувшись назад, наверное, честно себе скажут, что долго не могли осознать дзен этого ключевого слова. В статье приоткрываем завесу тайн применения ключевика this для тех, кто до сих пор в него не может… Welcome! Если вы возьмете справочник Шилдта по Java, то на 171 странице вы прочитаете о том, что ключевое слово this требуется для того, чтобы метод мог сослаться на вызвавший его объект. На этом, собственно можно было бы и закончить. Но нам нужна конкретика. Ключевое слово this {в примерах} - 1Как правило, применять this нужно в двух случаях:
  1. Когда у переменной экземпляра класса и переменной метода/конструктора одинаковые имена;
  2. Когда нужно вызвать конструктор одного типа (например, конструктор по умолчанию или параметризированный) из другого. Это еще называется явным вызовом конструктора.
Вот и все, на самом деле не так много, — всего два случая, когда применяется это страшное ключевое слово. Теперь давайте рассмотрим эти две ситуации на примерах.

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

Допустим, у нас есть класс Human, для которого определено поле «имя»: Ключевое слово this {в примерах} - 2Давайте для переменной name создадим сеттер (setter вполне рабочий и никакого подвоха здесь нет): Ключевое слово this {в примерах} - 3Обратите внимание, что в метод (сеттер) setName мы передаем переменную String newName. Мы ввели новую переменную и (в общем-то) могли назвать ее как угодно ведь она будет видна только в пределах {фигурных скобок} метода setName. Обратите внимание, что в сеттере есть одна строка:
name = newName;
То есть по факту мы ввели новую переменную newName и присвоили ее уже существующей в классе переменной name. Многим программистом казалось это странным, — вводить переменную с новым именем, если в итоге речь идет об одном и том же. Об имени в классе Human. Поэтому, разработчики языка задумались о том, чтобы удобно сделать использование одного имени переменной. Другими словами, зачем иметь два имени для переменной, обозначающей одно и то же. То есть хотелось бы сделать как-то так: Ключевое слово this {в примерах} - 4Но в этом случае возникает проблема. У нас теперь две переменные, которые называются одинаково. Один String name принадлежит классу Human, а другой String name его методу setName. Поэтому Java – машина не знает, какую переменную вы имеете ввиду, когда пишете строку в сеттере:
name = name;
Java берет самую близкую – name из метода setName:
Ключевое слово this {в примерах} - 5
и получается, что вы просто присваиваете значение переменной name из этого метода, ей же. Что конечно не имеет никакого смысла. Поэтому нужен был какой-то способ, чтобы отличить переменную name из класса Human, от переменной name из метода setName.Для решения этой проблемы и было введено ключевое слово this, которое в данном случае укажет, что нужно вызывать переменную не метода, а класса Human:
Ключевое слово this {в примерах} - 6
То есть this сошлется на вызвавший объект, как было сказано в начале статьи. В результате чего имя человека через сеттер setName будет установлено создаваемому объекту. Ниже приведен программный код без использования ключевого слова this. В коде создается объект класса Human и присваивается ему имя:
Ключевое слово this {в примерах} - 7
А ниже программный код с ключевым словом 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 {в примерах} - 9
Комментарии (99)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Senya
Уровень 15
6 апреля, 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);
    }
}
Алексей Барищук
Уровень 34
Expert
5 января, 14:34
public boolean equals(Object obj)
{
   if (this == obj)
    return true;
https://javarush.com/quests/lectures/questsyntaxpro.level10.lecture04 тут походу третий случай...
Бромгексин
Уровень 16
20 февраля, 12:45
вот ис this???
Oraz Janov Backend Developer
11 апреля 2023, 08:20
THIS is Хорошо
RomaSky QA Automation Engineer
17 января 2023, 04:07
Но неявно ключевое слово this передается во все методы...... .....и может быть использовано для обращения к объекту, вызвавшему метод. А можно пример чтобы "явно" понять данный вывод :)
Виталий Бабич
Уровень 4
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(какая то перемернная объект), то он заблокирует мьютекс уже объекта этой переменной и другие потоки просто не смогут обратиться к этой переменной, но смогут продолжить работу с другими переменными.
Стас
Уровень 38
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);
    }
}
пример стащил с раздела помощь
Иван Аканов
Уровень 26
15 июня 2023, 05:59
Спасибо bro! Искал как раз это применение!
Елена
Уровень 41
20 апреля 2022, 13:14
в каких случаях применяется второй способ this?
Qunjavi qunari в Java Inquisition
17 июля 2022, 11:17
"Вызов одного конструктора из другого может пригодиться тогда, когда у вас несколько конструкторов и вам не хочется в новом конструкторе переписывать код инициализации, приведенный в конструкторе ранее."
Peter
Уровень 14
1 апреля 2022, 21:42
Впринципе хорошо, но можно было ещё добавить про затенение переменных, если такая же переменная создаётся в методе. А так же добавить, что со статическими переменными this не работает и тогда чтобы вывести статическую переменную изза затенения новой, нужно обращаться к переменной чере Класс.
human.name
Anonymous #2981142
Уровень 4
29 января 2022, 17:05
Шикарно