This java что это
Перейти к содержимому

This java что это

  • автор:

Что означает 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
987 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, то ответ дан ранее.

Конструкторы, ключевое слово 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 Обобщенные интерфейсы, наследование обобщенных классов

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

This java что это

Но неявно ключевое слово this передается во все методы. . и может быть использовано для обращения к объекту, вызвавшему метод. А можно пример чтобы «явно» понять данный вывод 🙂

31 августа 2022
А в многопоточности когда мы по this синхронизируем блок кода syncronized(this)?
Стас Уровень 38
26 августа 2022
Потому что

 this 

не страшно.
Михаил Уровень 20
19 июля 2022
Надо доп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); >> 

пример стащил с раздела помощь
Елена Уровень 41
20 апреля 2022
в каких случаях применяется второй способ this?
Peter Уровень 14
1 апреля 2022

Впринципе хорошо, но можно было ещё добавить про затенение переменных, если такая же переменная создаётся в методе. А так же добавить, что со статическими переменными this не работает и тогда чтобы вывести статическую переменную изза затенения новой, нужно обращаться к переменной чере Класс.

 human.name 

29 января 2022
618 Уровень 20
15 января 2022
Крутая статья. А если вернуть ключевое слово в методе (return this;) то что вернёт метод?
Андрей Уровень 51
10 января 2022
Стало немного понятно.
Сообщество

JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.

Подписывайтесь
Язык интерфейса
«Программистами не рождаются» © 2023 JavaRush
Скачивайте наши приложения
«Программистами не рождаются» © 2023 JavaRush

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Java ключевое слово this, как работает?

Я знаю разные ситуации в которых можно использовать ключевое слово this в Java. Но одно определение мне до сих пор непонятно «ссылка на текущий обьект», на какой текущий?
Что если в классе не создано обьектов?
И самое главное, что если в классе несколько обьектов?
Какой из них «текущий»?

Я читал в одной статье что при создании класса неявно создаётся обьект класса, именно this на него и ссылается. Но тогда слово this не может заменять обьект при вызове переменной обьекта, по типу object.variable тоже самое что this.variable, но как это возможно? Ведь this указывает на некий обьект который мы не создавали. Кароче это определение совсем не ясное «текущий обьект».

ПС — Также не совсем понятно его использование (this и super) для вызова из одного конструктора другого, ни разу в жизни не пригодилось, и даже не могу представить ситуацию в которой такое может пригодится.

ПСС — Перечитал кучу статей, книг, видео, так и не понял сути «текущий обьект» так как не понятно что за обьект и что делать если обьектов нет или их несколько.

  • Вопрос задан более трёх лет назад
  • 11018 просмотров

2 комментария

Простой 2 комментария

Сергей Горностаев @sergey-gornostaev Куратор тега Java
Какие именно книги вы читали?

Также не совсем понятно его использование (this и super) для вызова из одного конструктора другого, ни разу в жизни не пригодилось, и даже не могу представить ситуацию в которой такое может пригодится.

super нужен для обращения к родительскому инстансу или родительскому конструктору. Если у вас будет иерархия классов (тем более — сложная), то поймёте, зачем нужны эти слова.
А по поводу объектов и слова this. Почитайте, например, Head First Java. Там довольно понятные рисунки. Каждый объект — это, по сути, дом, созданный по некоторому чертежу. В данном случае чертёж — это класс. Дома строятся на некоторой площади. Эта площадь — это куча объектов. При создании объекта (постройки дома) ему присваивается некоторый адрес (если брать аналогию с домами, то это улица и номер дома), адрес в куче. Он сохраняется внутри этого объекта (опять-таки, если брать аналогию с домом — то это табличка на доме с его адресом). Дальше можно привести такую аналогию. В каждый дом и в какое-либо его помещение может войти любой человек. Программа также входит в методы объектов. То есть в данном случае, программа — это этот человек, а метод — это комната дома, куда он вошёл. Соответственно, перед тем, как войти, человек смотрит номер дома, и запоминает его. И когда этот человек что-то делает внутри комнаты и видит где-то упоминание этого дома, он вспоминает, какой адрес этого дома и автоматически его использует, подставляет. Также делает и программа, когда идёт по телу методу. Понятно?

Решения вопроса 0
Ответы на вопрос 4

GavriKos

У вас путаница с терминами. Класс — это всего лишь «инструкция», «схема». Просто описанный в коде класс ничего не может делать. Чтобы он что то делал — нужно создать объект класса. Это делается явно через new.
Возьмем пример — ручка. У вас есть описание класса ручка. Но это еще не объект — всего лишь описание. Сделав New — вы создадите экземпляр ручки. И экземпляров может быть сколько угодно, и с разными параметрами (цвет, размер и прочее) — но все это ручки.

Так вот. this в ЭКЗЕМПЛЯРЕ указывает НА ЭТОТ САМЫЙ экземпляр.

Ответ написан более трёх лет назад
Нравится 4 17 комментариев
Сергей Горностаев @sergey-gornostaev Куратор тега Java

С ручками аналогия не очень понятная. Для класса лучше подойдёт аналогия архитектурного проекта здания. Проект один, а зданий наклепать по нему можно множество. В проекте жить нельзя, а в построенном здании можно. А ключ от дома в руке его владельца — это this, у каждого свой.

GavriKos

Сергей Горностаев, о, да, ваш пример лучше )

redasya

redasya @redasya Автор вопроса

GavriKos, Какой этот самый? Ручек может быть миллион. Также вы не правы, можно написать софт без единого обьекта и слова «new», в чём проблема то?

redasya

redasya @redasya Автор вопроса

Сергей Горностаев, Если this у каждого свой, термин «текущий обьект», не имеет смысла, если у класса 10000000 обьектов зданий, на какой обьект укажет this? Я же чётко поставил вопрос.

GavriKos

redasya, Для каждой ручки this укажет именно на эту ручку. Написать без new можно, но тогда не будет объекта класса и соответственно — не будет this.

е имеет смысла, если у класса 10000000 обьектов зданий,

проиллюстрируйте это кодом.

redasya

redasya @redasya Автор вопроса

GavriKos, Ну не 1000000 а скажем 2 обьекта, на какой укажет this? Именно на эту, на которую из них? Как компилятор это поймёт? Силой мысли? Да причём тут код, вот есть класс Person и есть два обьекта Vasya и Petya, и какой из них «текущий обьект»?!

GavriKos

redasya, у васи this — вася, у пети this — петя. this — это поле класса. Соответственно в каждом экземпляре оно свое.

GavriKos

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

Сергей Горностаев @sergey-gornostaev Куратор тега Java

class DumbExample < private int value; public void revealTheMystery(int someValue) < this.value = someValue; >public static void main(String args[]) < DumbExample obj1 = new DumbExample(); DumbExample obj2 = new DumbExample(); obj1.revealTheMystery(42); // В этом вызове метода this указывает на obj1 obj2.revealTheMystery(666); // В этом вызове метода this указывает на obj2 >>

redasya

redasya @redasya Автор вопроса

Сергей Горностаев, Это не тот вариант. Тут указывается на поле обьекта, я говорю именно про указание на «текущий обьект».

Сергей Горностаев @sergey-gornostaev Куратор тега Java
redasya, что-нибудь поменялось?

public void revealTheMystery()

redasya

redasya @redasya Автор вопроса

GavriKos, Вы не понимаете очём я, я не про поля класса, про поля класса всё понятно.
he various usage of keyword Java ‘THIS’ in Java is as per the below,

It can be used to refer current class instance variable — Это поля
It can be used to invoke or initiate current class constructor
It can be passed as an argument in the method call
It can be passed as argument in the constructor call
It can be used to return the current class instance — Вот это непонятно

Сергей Горностаев @sergey-gornostaev Куратор тега Java
redasya, ок, ничего принципиально не меняется

public DumbExample revealTheMystery()

GavriKos

redasya, это все про один и тот же this. Щас попробуем с другой стороны. Все классы в Java — наследники (неявные) класса Object. У класса Object есть поле — this. Обычное поле класса. Соответственно оно есть и у наследников. Когда вы создаете экземпляр класса (делаете new) — джава-машина в поле this кладет ссылку на то, что было создано при помощи new.
Например:

YourClass instance = new YourClass(); YourClass instance2 = new YourClass();

в instance как вы понимаете — экземпляр класса YourClass и в instance2 — тоже экземпляр, но другой. Это два разных экземпляра (объекта). Соответственно их поля могут иметь разные значения. this — поле. Для instance — оно будет равно instance, для Instance2 — instance2.
Соответственно когда вы будете вызывать у какого то ЭКЗЕМПЛЯРА (методы вызываются у экземпляров, не у классов), то можете работать внутри метода только с полям этого ЭКЗЕМПЛЯРА. И вот в поле this будет ссылка на этот экземпляр, у которого вызван метод.
Продолжая код:

instance.someField = 1; instance2.someField = 2; public int YourClass::GetField()

Если вы попытаетесь вызвать метод GetField у instance — вернется 1. Если у instance2 — вернется 2. Вот точно так же и с this:

public YourClass YourClass::GetThis() < return this; >instance == instance.GetThis() //true instance2 == instance2.GetThis() //true instance == instance2.GetThis() //false

КОд не на джаве, но принцип тот же
Денис Загаевский @zagayevskiy Куратор тега Java
GavriKos, в какой момент this стал полем?

GavriKos

Денис Загаевский, это попытка объяснить на пальцах. Тут уж не до терминов )
Денис Загаевский @zagayevskiy Куратор тега Java
GavriKos, человек не понимает концепцию создания экземпляра класса, а вы ему про поля в обжекте.

Похоже тут никто из комментаторов понятия не имеют, как на самом деле работает их код.

Вы пишите такой код:

class Foo < void foo(String str) < . >; > . Foo f = new Foo(); f.foo("abc");

Компилятор же сгенерирует байткод, который примерно соответствует такому коду:

class Foo < static void foo(Foo this, String str) < . >; > . Foo f = new Foo(); Foo.foo(f, "abc");

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

Так что по сути this это не обычное ключевое слово, это просто имя параметра в методе.

Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать

Sputterspark

Elmo Sputterspark @Sputterspark

Методы всегда вызываются у объектов, а не классов, если они не статические. Вот на тот объект, у которого вызван метод, this и ссылается.

Ответ написан более трёх лет назад

redasya

redasya @redasya Автор вопроса

«если они не статические» Кагбы сами сказали))) Фэйспалм тут не к чему, класс и обьект это ни одно и тоже, почему то в большинстве статей это считается одним и тем же. Я кажется задал другой вопрос, какой обьект? У класса может быть 100000 обьектов, на который из них ссылается this?

redasya

redasya @redasya Автор вопроса

Вы же понимаете что можно и не создавать обьект и никто тебе руки не отрубит, тогда на что будет указывать this? И на что он будет указывать, если обьектов класса миллион? на который из них?

Sputterspark

Elmo Sputterspark @Sputterspark

redasya, если не создавать объект, то this не на что не будет указывать, его просто не существует в статическом контексте. А если объектов класса миллион, то будет указывать на тот, метод которого вызван. Фейспалм тут очень даже причём.

redasya, если будет триллион объектов одного класса, то у каждого объекта будет свой this.
Вот такая аналогия — есть тысяча абсолютно одинаковых людей (клонов). У каждого есть переменная «я». Каждый может сказать «я» только про самого себя, но не про другого человека, так как «я» у каждого своя.

redasya

redasya @redasya Автор вопроса

Артём Петренков, «на тот, у которого вызвали метод» — пример дайте. Я не понимаю какой обьект текущий и как это определяется, в классе может быть несколько обьектов.

redasya

redasya @redasya Автор вопроса

Артём Петренков,
he various usage of keyword Java ‘THIS’ in Java is as per the below,

It can be used to refer current class instance variable
It can be used to invoke or initiate current class constructor
It can be passed as an argument in the method call
It can be passed as argument in the constructor call
It can be used to return the current class instance — Вот это!

redasya, ну если хотите подробностей про внутренности, то при вызове метода у объекта, например, m.setPage(10), вызывается метод у класса, M.setPage(m, 10), первым параметром передаётся ссылка на этот объект. Собственная переменной this и присваивается значение ссылки на этот объект

jamakasi666

Дмитрий Александров @jamakasi666 Куратор тега Java
Просто IT’шник.

Если я правильно настроился на волну тс то разжую доступными словами.
Для начала нужно чтобы было правильное понимание происходящего в java а именно:
1) в java всё есть объект, вот прям все все* . Это означает что абсолютно что угодно отнаследовано от класса Object
2) есть(могут быть) различия того что именно содержится в классе в исходном коде и коде при выполнении программы а также после ее компиляции. Если простым языком то это может предстать так
— в коде у класса есть только метод foo()
— после компиляции оказывается что в нем после некоторых событий типа аннотаций появляется еще и метод bar(). Тут важно то что он появится * у всех инстансов от этого класса
— при выполнении может оказаться так что метод foo() будет подменен другим кодом. Это уже рефлексия.
— при выполнении может оказаться что у НЕКОТОРЫХ инстансов класса внутри окажется еще и метод mymethod(). Т.е. не у всех а именно у некоторых инстансов.
3) при выполнении программы * для абсолютно всего ВСЕГДА создается явно или не явно инстанс, даже для статического класса. Т.е. ты в коде может и не создавал инстанс явно через new, это было сделано рантаймом гдето в недрах явы!
4) статический класс отличается от обычного только тем что статический всегда указывает только и только* на 1 единственный инстанс
5) super() , означает что будет вызов метода\конструктора РОДИТЕЛЯ
6) super , БЕЗ СКОБОК, означает переход к переменным РОДИТЕЛЯ. Также можно вызвать и метод РОДИТЕЛЯ.
7) this всегда указывает именно на текущий инстанс класса. Другими словами представь что класс это область видимости и когда ты пишешь this ты явно говоришь что это относится именно к этому инстансу а не классу.

*гуру молчите что это не совсем так в особенных фундаментальных моментах
инстанс — экземпляр класса, т.е. грубо говоря он создается через new явно или не явно

Если всеравно непонятно то могу набросать примером простеньких. Также рекомендую почитать
это и примеры тут

Обобщая выше сказанное(с нюансами):
— в java ВСЁ и ВСЕГДА это инстанс какого либо класса
— исходя из пункта выше ВСЕГДА на любой класс существует хотябы один инстанс
— исходя из пункта выше часто бывают случаи когда необходимо обратиться к переменной\методу родителя через super. Также возникают необходимости обратиться к методу\переменной именно этого конкретного инстанса или передать этот инстанс куда либо дальше не имея ссылки на этот инстанс.

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

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