Что делает this в java
Перейти к содержимому

Что делает this в java

  • автор:

Ключевое слово this

Иногда требуется, чтобы метод ссылался на вызвавший его объект. Ключевое слово this в Java используется в теле любого метода для ссылки на текущий объект.

Рассмотрим конструктор, в котором параметры имеют те же имена, что и переменные класса. В этом случае параметры перекрывают область видимости переменных класса и мы не можем напрямую обратится к переменным класса. Чтобы это сделать используется ключевое слово this:

Box(double width, double height, double depth)

В этом примере использование ключевого слова this не является необходимым — можно обойтись и без него:

Box(double w, double h, double d)

2. Использование ключевого слова this() в конструкторе

Второй вариант использования ключевого слова this() — с его помощью можно вызвать один конструктор из другого. Вызов this() может находиться только в первой строчке конструктора:

public class Toy < String name; int cost; String manufacturer; int age; public Toy(String name, int cost, String manufacturer, int age) < this(name, cost, manufacturer); this.age = age; System.out.println("В конструкторе с четырьмя параметрами"); >public Toy(String name, int cost, String manufacturer) < this(); this.name = name; this.cost = cost; this.manufacturer = manufacturer; System.out.println("В конструкторе с тремя параметрами"); >public Toy() < System.out.println("В конструкторе по умолчанию"); >>
public class ToyDemo < public static void main(String[] args) < Toy toy = new Toy("Кукла", 34, "Disney", 3); >>
В конструкторе по умолчанию В конструкторе с тремя параметрами В конструкторе с четырьмя параметрами
  • Процедурное и объектно-ориентированное программирование
  • Принципы ООП
  • Классы и объекты
  • Конструктор
  • Перегрузка
  • Стек и куча
  • Передача объектов в методы
  • Java varargs
  • Рекурсия
  • Сборщик мусора и метод finalize
  • Наследование
  • Ключевое слово super
  • Модификаторы доступа
  • Геттеры и сеттеры
  • Переопределение методов
  • Абстрактные классы и методы
  • Ключевое слово final
  • Задания

Использование ключевого слова «this» в Java

Одной из основных особенностей языка программирования Java является его объектно-ориентированный подход. Это означает, что большую часть кода мы пишем внутри классов, которые представляют собой модели объектов реального мира или абстракций. Внутри этих классов мы определяем переменные (состояния объектов) и методы (поведение объектов).

Ключевое слово this в Java используется для ссылки на текущий объект. Другими словами, this ссылается на экземпляр класса, внутри которого оно используется.

public class Car < private String color; public Car(String color) < this.color = color; >>

В этом примере this.color означает цвет текущего объекта Car , а color — это параметр конструктора. Без использования this переменная color в конструкторе ссылается на себя, а не на переменную класса.

Точно так же ключевое слово this можно использовать для вызова методов текущего объекта. Это может быть полезно, если есть необходимость уточнить, что метод должен быть вызван именно для текущего объекта.

public class Car < private int speed; public void increaseSpeed() < this.setSpeed(this.speed + 10); >private void setSpeed(int speed) < this.speed = speed; >>

В данном случае this.setSpeed() вызывает метод setSpeed() для текущего объекта Car .

Если же мы просто напишем setSpeed() , то это будет то же самое, что и this.setSpeed() , поскольку по умолчанию все методы вызываются для текущего объекта.

Итак, ключевое слово this в Java используется для указания на текущий объект в контексте класса. Это особенно полезно, когда есть необходимость различать между переменными класса и параметрами метода или конструктора с одинаковыми именами.

Конструкторы, ключевое слово this, инициализаторы

На предыдущем занятии мы увидели как объявляются классы и создаются их экземпляры с помощью оператора:

ссылка = new имя_класса();

В частности, вот такой строчкой:

Point pt = new Point();

создавали объект класса Point:

class Point { int x, y; }

В действительности, в момент создания объекта всегда происходит вызов специального метода (функции) класса, который называется конструктор:

Но у нас в классе Point нет никаких методов, там объявлены только две переменные x, y. Все так, но в Java в любой класс автоматически добавляет конструктор по умолчанию, если явно не записаны никакие другие конструкторы. Именно этот конструктор по умолчанию и вызывался при создании объектов класса Point.

Чтобы все было понятнее, давайте объявим свой конструктор в этом классе. Для этого используется такой синтаксис:

имя_класса([аргументы]) <
// тело конструктора (набор операторов)
>

И в нашем случае его можно прописать так:

class Point { int x, y; Point() { x = -1; y = -1; } }

Смотрите, мы указываем, что при создании нового экземпляра класса, значения полей x, y будут равны -1. Проверим это, создадим объект и выведем значения координат в консоль:

Point pt = new Point(); System.out.println("x = " + pt.x + ", y = " + pt.y);

Отображаются -1. Это как раз следствие работы конструктора, который мы прописали в классе. При этом, конструктор по умолчанию больше не существует и остается только тот, что мы указали.

А что если мы захотим прописать два конструктора и к существующему добавить еще один:

Point(int argx, int argy) { x = argx; y = argy; }

Так тоже можно делать. Теперь наш класс содержит оба конструктора и мы можем вызывать любой из них при создании объектов:

Point pt = new Point(); Point pt2 = new Point(1, 2); System.out.println("x = " + pt.x + ", y = " + pt.y); System.out.println("x = " + pt2.x + ", y = " + pt2.y);

Это называется перегрузкой конструкторов, когда в одном классе несколько конструкторов с разными аргументами. На практике это используется довольно часто.

Ключевое слово this

Давайте теперь предположим, что во втором конструкторе имена аргументов называются также как и поля:

Point(int x, int y) { x = x; y = y; }

Очевидно, что здесь x, y будут восприниматься как локальные аргументы и никакого отношения к переменным класса x, y они не будут иметь. Но, можно ли как то явно указать, что мы хотим обратиться именно к полям объекта, а не к аргументам конструктора? Да, можно, и делается это с помощью специального ключевого слова this:

Point(int x, int y) { this.x = x; this.y = y; }

По смыслу this – это ссылка на текущий экземпляр объекта. То есть, если нам внутри самого объекта требуется оперировать ссылкой на него, то для этого используется ключевое слово this. Мало того, через this можно вызывать один конструктор из другого. Например, добавим в класс Point еще одно поле color – цвет точки. И будем по умолчанию инициализировать его нулем:

class Point { int x, y; int color; Point() { x = -1; y = -1; color = 0; } Point(int x, int y) { this.x = x; this.y = y; color = 0; } }

Смотрите что получается. У нас конструкторах происходит дублирование кода. Это плохой стиль программирования. Чтобы этого избежать, можно во втором конструкторе вызвать сначала первый для начальной инициализации полей, а затем, изменить значения координат x, y:

Point(int x, int y) { this(); this.x = x; this.y = y; }

Вот эта строчка this(); как раз выполняет вызов первого конструктора перед изменением полей x, y. В результате, никакого дублирования не происходит. Вот так двояко можно применять ссылку this: и для доступа к полям текущего объекта, и для вызова конструкторов.

Инициализаторы

Давайте еще раз внимательно посмотрим на пример нашего класса и зададимся вопросом: что делает первый конструктор без аргументов? Фактически, он выполняет начальную инициализацию полей класса Point. Именно поэтому мы его отдельно вызываем во втором конструкторе. Но это не лучший ход. В классах языка Java можно создавать специальный блок, который так и называется – инициализатор. Он автоматически выполняется один раз при создании объекта до вызова конструкторов. Записывается инициализатор следующим образом:

class Point { int x, y; int color; // инициализатор { x = -1; y = -1; color = 100; } // конструкторы Point() { } Point(int x, int y) { this.x = x; this.y = y; } }

Смотрите, здесь в отдельном блоке задаются начальные значения всех переменных класса, а затем, отдельно вызываются конструкторы. При этом, вызывать первый конструктор из второго уже нет необходимости – данные уже инициализированы указанными значениями. Это очень удобно.

Глядя на первый конструктор, в котором нет никакой реализации, возникает соблазн его попросту убрать из класса Point. Давайте попробуем это сделать и посмотрим к чему это приведет:

class Point { int x, y; int color; // инициализатор { x = -1; y = -1; color = 100; } // конструкторы Point(int x, int y) { this.x = x; this.y = y; } }

При запуске программы компилятор выдал ошибку, что невозможно создать объект при вызове конструктора без аргументов. Вместе с тем, нам бы хотелось иметь такую функциональность – создавать экземпляры без указания конкретных координат. Именно для этого следует иметь первый конструктор без аргументов.

Путь кодера

Подвиг 1. Объявить класс Rect для представления прямоугольника, в котором хранятся две координаты: верхнего левого и правого нижнего углов. Реализовать три конструктора: первый – без аргументов; второй с четырьмя аргументами для двух координат; третий – с четырьмя аргументами (координата левого верхнего угла, ширина и высота). Создать несколько экземпляров с вызовом разных конструкторов и выводом значений полей в консоль.

Подвиг 2. Объявить класс Triangle, хранящий три координаты вершин. Координаты представить в виде ссылок на класс Point, который рассмотрен на этом занятии. Реализовать два конструктора: без аргументов и с шестью аргументами (по два на каждую координату). Создать два объекта, вывести координаты вершин по каждому объекту в консоль.

Подвиг 3. Объявить класс Line для представления линии на плоскости, хранящий две координаты: начало и конец линии. Создать два объекта этого класса и в функции main() определить: пересекаются ли эти две линии.

Видео по теме

#11 Концепция объектно-ориентированного программирования (ООП)

#12 Классы и создание объектов классов

#13 Конструкторы, ключевое слово this, инициализаторы

#14 Методы класса, сеттеры и геттеры, public, private, protected

#15 Пакеты, модификаторы конструкторов и классов

#16 Ключевые слова static и final

#17 Внутренние и вложенные классы

#18 Как делается наследование классов

#19 Ключевое слово super, оператор instanceof

#20 Модификаторы private и protected, переопределение методов, полиморфизм

#21 Абстрактные классы и методы

#22 Интерфейсы — объявление и применение

#23 Интерфейсы — приватные, статические и дефолтные методы, наследование интерфейсов

#24 Анонимные внутренние классы

#25 Перечисления (enum)

#26 Обобщения классов (Generics)

#27 Ограничения типов, метасимвольные аргументы, обобщенные методы и конструкторы

#28 Обобщенные интерфейсы, наследование обобщенных классов

© 2024 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта

Что означает Class.this

Получается, что this — это ссылка на объект. Тогда у меня возникает вопрос, что означает эта запись:

Что здесь может возвращать this, если в классе я не создавал никаких объектов. Чем здесь является this?

Отслеживать
задан 20 мар 2021 в 10:42
user428447 user428447
Можно же посмотреть дебагером/принтом.
20 мар 2021 в 10:43

ru.stackoverflow.com/q/1258341/177345 — это один и тот же вопрос? Если да, то не нужно создавать новые дубликаты, делайте уточнения в уже заданном (кнопка «править» под вопросом)

20 мар 2021 в 12:06

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Записи типа Class.this используются во вложенных или анонимных классах, когда из них нам нужно сослаться на объект включающего их класса. Class — имя внешнего (включающего) сласса, this — ссылка на экземпляр внешнего (включающего) класса. Если вы вложенном классе или анонимном классе обратитесь, просто по this, то вы сошлётесь на текущий объект этого вложенного или анонимного класса, а не на объект внешнего.

Отслеживать
ответ дан 20 мар 2021 в 18:32
997 1 1 золотой знак 3 3 серебряных знака 16 16 бронзовых знаков

Да, это я уже выяснил из просторов инета, но я не понимаю на какой объект мы ссылаемся при такой записи, если в своем классе я не создавал никакого объекта, например когда в своем классе(Info) я создаю объект Intent и в первый параметр конструктора я пишу Info.this. Так на какой объект я ссылаюсь если объектов в классе Info я не создавал?

– user428447
21 мар 2021 в 9:52

@Михаил Вы имеете в виду в первый параметр конструктора объекта Intent? Тогда так: На этапе выполнения, во время создания объекта класса Info в нём будет создан объект класса Intent и в качестве аргумента в конструктор этого объекта (Intent) будет передан сам объект Info, то есть текущий объект класса Info, но в такой ситуации вы можете использовать просто — this. Использование Info.this в этом случае — это просто для удобочитаемости, этого можно было и не писать

21 мар 2021 в 10:59

@Михаил если же вы не получаете объект Intent в определении класса Info, а определяете класс Intent, как вложенный в класс Info, то ответ дан ранее.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *