Skip to content
Содержание

Переходная лекция

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

Ссылочные типы данных

В первой лекции я кратко их затрагивал, но не стал подробно останавливаться (и сейчас, кстати, тоже не стану).
Итак, в 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() используется для сравнения объектов согласно смыслу, который определён этим методом.