Предположим, во время выполнения метода вы хотели бы получить ссылку на текущий объект. Так как эта ссылка передается компилятором
//: initialization/Apricot.java public class Apricot {
void pickO { /* .. */ } void pit() { pickO; /*..*/} } ///:-
Внутри метода pit()
//: initialization/Leaf.java // Simple use of the "this" keyword.
public class Leaf { int i = 0; Leaf increment О { i++;
return this;
}
void printO {
System, out. printlnC'i = " + i).
}
public static void main(String[] args) { Leaf x = new LeafO;
x.i ncrement().i ncrement() i ncrement().pri nt О;
}
} /* Output: i = 3 *///:-
Так как метод increment() возвращает ссылку на текущий объект посредством ключевого слова this, над одним и тем же объектом легко можно провести множество операций.
Ключевое слово this также может пригодиться для передачи текущего объекта другому методу:
//. initialization/PassingThis java
class Person {
public void eat(Apple apple) {
Apple peeled = apple.getPeeledО; System.out.println("Yummy");
}
}
class Peeler {
static Apple peel(Apple apple) {
// .. Снимаем кожуру
return apple; // Очищенное яблоко
}
}
class Apple {
Apple getPeeledO { return Peeler.peel(this); }
}
public class PassingThis {
public static void main(String[] args) { new Person О eat (new AppleO);
}
} /* Output: Yummy *///.-
Класс Apple вызывает Peeler.peel() — вспомогательный метод, который по какой-то причине должен быть оформлен как внешний по отношению к Apple (может быть, он должен обслуживать несколько разных классов, и вы хотите избежать дублирования кода). Для передачи текущего объекта внешнему методу используется ключевое слово this.
Вызов конструкторов из конструкторов
Если вы пишете для класса несколько конструкторов, иногда бывает удобно вызвать один конструктор из другого, чтобы избежать дублирования кода. Такая операция проводится с использованием ключевого слова this.
Обычно при употреблении this подразумевается «этот объект» или «текущий объект», и само слово является ссылкой на текущий объект. В конструкторе ключевое слово this имеет другой смысл: при использовании его со списком аргументов вызывается конструктор, соответствующий данному списку. Таким образом, появляется возможность прямого вызова других конструкторов:
// initialization/Flower.java // Calling constructors with "this" import static net.mindview.util.Print.*;
public class Flower { int petal Count = 0; String s = "initial value"; Flower(int petals) {
petal Count = petals;
print("Конструктор с параметром int, petalCount= " + petal Count),
}
Flower(String ss) {
print("Конструктор с параметром String, s = " + ss); s = ss;
}
Flower(String s, int petals) { this(petals),
//! this(s); // Вызов другого конструктора запрещен! this.s = s; // Другое использование "this" print("Аргументы String и int");
}
FlowerО { thisC'hi". 47).
printC'KOHCTpyKTop по умолчанию (без аргументов)"),
}
void printPetalCountO { //! this(11), // Разрешается только в конструкторах! print("petal Count = " + petal Count + " s = "+ s);
}
public static void main(String[] args) { Flower x = new Flower(); x printPetalCountO,
}
} /* Output-
Конструктор с параметром int, petalCount= 47 Аргументы String и int Конструктор по умолчанию (без аргументов) petal Count = 47 s = hi */// ~
Конструктор Flower(String s, int petals) показывает, что при вызове одного конструктора через this вызывать второй запрещается. Вдобавок вызов другого конструктора должен быть первой выполняемой операцией, иначе компилятор выдаст сообщение об ошибке.
Пример демонстрирует еще один способ использования this. Так как имена аргумента s и поля данных класса s совпадают, возникает неоднозначность. Разрешить это затруднение можно при помощи конструкции this.s, однозначно определяющей поле данных класса. Вы еще не раз встретите такой подход в различных Java-nporpaMMax, да и в этой книге он практикуется довольно часто.
Метод printPetalCountO показывает, что компилятор не разрешает вызывать конструктор из обычного метода; это разрешено только в конструкторах.
Значение ключевого слова static