Appearance
Переходная лекция
В этой лекции быстренько пробежимся по небольшим штукам, которые я не давал в прошлых лекциях, чтобы не забивать вам голову. После этого переходим к ООП.
Ссылочные типы данных
В первой лекции я кратко их затрагивал, но не стал подробно останавливаться (и сейчас, кстати, тоже не стану).
Итак, в Java типы делятся на две большие категории: примитивные и ссылочные. Примитивные мы знаем.
java
int age = 20;
double price = 15.5;
boolean isStudent = true;
char letter = 'A';
Здесь переменная хранит непосредственно значение.
С ссылочным типом всё чуть веселее. Переменная хранит ссылку на объект, а сам объект лежит где-то в памяти.
java
String name = "Beatrice";
name - переменная ссылочного типа String. Ссылка - это не сам объект. Это значение, которое позволяет обратиться к объекту (о том, что такое объект, рассказывается в вводной лекции блока ООП).
К ссылочным типам относятся, например:
java
String
int[] // не конкретно массив целых чисел, а в принципе все массивы
ArrayList
Scanner
...а также все классы.
Зачем вообще нужна эта информация:
java
int a = 5;
int b = a;
b = 20;
IO.println(a); // 10
Вполне предсказуемое поведение. b получила копию значения, поэтому изменения b не будут влиять на a. А теперь массив:
java
int[] a = {10, 20};
int[] b = a;
b[0] = 100;
IO.println(a[0]); // 100
Похожий пример я приводил в лекции по массивам, но напомню: b получила не копию массива, а копию ссылки на массив. Получается, что массив по-прежнему один, просто теперь на него указывают две ссылки. Поэтому изменения b отразились на a.
Поэтому важно запомнить:
В Java при присваивании всегда копируется значение переменной. Для ссылочного типа этим значением является ссылка.
null
null - специальное значение для ссылочных типов данных. Оно буквально обозначает "ссылка сейчас не указывает ни на какой объект".
java
String name = null;
Ссылка есть, но она ни на что не ссылается. А теперь самое смешное - работа с null.
java
String name = null;
IO.println(name.length()); // NullPointerException
Мы попытались обратиться к объекту через ссылку, а объекта там не оказалось. NPE (NullPointerException, исключение нулевого указателя) - крайне коварное исключение. В Java почти всё является объектом, а значит почти всё может иметь null-ссылку, из-за чего они выскакивают в самых неожиданных местах в самое неудобное время.
Если нужно проверить наличие объекта по ссылке, то можно использовать такую конструкцию:
java
String name = null;
if (name != null) {
IO.println(name.length());
}
Если вместо объекта переменная name будет ссылаться на null, то тело условия просто не выполнится и исключения не возникнет.
Область видимости
В Java есть понятие "область видимости" (она же scope). Область видимости - это область программы, где переменная "существует" и к ней можно обратиться. Если упростить, то переменная видна только внутри тех фигурных скобок, где она была объявлена. Примеры:
java
public static void main(String[] args) {
int x = 10;
if (x > 5) {
int y = 20;
System.out.println(x); // OK
System.out.println(y); // OK
}
System.out.println(x); // OK
System.out.println(y); // Переменная у определена в блоке if и здесь не видна
}
То же самое с циклами:
java
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
System.out.println(i); // ошибка
И с методами:
java
static void test() {
int x = 10;
}
public static void main(String[] args) {
System.out.println(x); // ошибка
}
== и .equals()
Тут всё просто: == сравнивает значения для примитивов и ссылки для ссылочных типов.
java
int a = 10; // примитивы
int b = 10;
IO.println(a == b); // true
Потому что это два разных объекта. А теперь ссылочный тип:
java
String a = new String("Hello");
String b = new String("Hello");
IO.println(a == b); // false
Объекты содержат одинаковый текст, но это разные объекты.
Для сравнения содержимого используется:
java
a.equals(b);
Этот метод есть у каждого класса в Java.
Если очень кратко:
Для ссылочных типов
==проверяет, являются ли две ссылки ссылками на один и тот же объект.equals()используется для сравнения объектов согласно смыслу, который определён этим методом.