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
Комментарии (98)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Алексей Барищук
Уровень 28
Expert
5 января, 14:34
public boolean equals(Object obj)
{
   if (this == obj)
    return true;
https://javarush.com/quests/lectures/questsyntaxpro.level10.lecture04 тут походу третий случай...
Бромгексин
Уровень 14
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
Шикарно
618
Уровень 20
15 января 2022, 19:45
Крутая статья. А если вернуть ключевое слово в методе (return this;) то что вернёт метод?
Dennfon
Уровень 7
26 января 2022, 11:20
Если методы перегружены, то метод как показала практика, будет работать как конструктор, т.е.на практике думаю, такое редко увидишь. но в тренировочном коде было забавно.
int summ(int a, int b, int c, int d) {
        int result = a + b + c + d;
        System.out.println(result);
        return result;
    }

    int summ(int a, int b, int c) {
        return this.summ(a, b, c, 0);
    }

    int summ(int a, int b) {
        return this.summ(a, b, 0, 0);
    }
P.S. Для лучшего перегруза конструктора, и работы с this лучше писать самый полный конструктор, а уже в не полных конструкторах заменять не используемые параметры на null или 0 (дефолтное значение) в зависимости от типа переменной.
public class Employee {
    int id;
    String surname;
    int age;
    double salary;
    String department;

    public Employee(int id, String surname, int age, double salary, String department) {
        this.id = id;
        this.surname = surname;
        this.age = age;
        this.salary = salary;
        this.department = department;
    }
 //Замена последнего элемента на - null
    public Employee(int id, String surname, int age, double salary) {
        this(id,surname,age,salary,null);
    }

//Замена 3 и 5 элемента на 0 и null
    public Employee(int id, String surname, double salary) {
        this(id,surname,0,salary,null);
    }
}
Artem Sokolov Android Developer в Oracle
9 мая 2022, 17:50
Вернёт объект вызывающий этот метод:)
Maria Karpikova
Уровень 20
18 августа 2023, 13:30
У меня и без this работает.