Передача и возврат ссылочных типов
Введено| English | Значение |
|---|---|
| NullPointerException/nʌl ˈpɔɪntə ekˈsepʃn/ | NullPointerException |
Изменение объекта отличается от переназначения параметра
- Вызывающий код ссылается на студента со счётом 10. Выполняется метод s.addScore(5); затем s = new Student("Other");
- Счёт исходного общего объекта становится 15. Переназначение локального параметра не меняет переменную вызывающего кода, так как Java копирует значение ссылки в параметр.
Передача объекта в метод
- Java копирует значение ссылки в параметр метода; сам объект не копируется. Параметр метода указывает на тот же самый объект, что и переменная вызывающего кода.
- Следовательно, изменения, которые метод вносит в объект, видны для вызывающего кода. И примитивные, и ссылочные аргументы передаются по значению; скопированная ссылка по-прежнему может обращаться к общему объекту.
Примитивы против объектов как аргументов
- Аргумент примитивного типа копируется — метод не может изменить переменную вызывающего кода. Для аргумента объекта скопированная ссылка указывает на тот же объект — метод может изменять (мутировать) этот объект.
changeInt(x)не изменяетx;student.addScore(10)изменяет этого студента. Задайте вопрос: мутирует ли метод общий объект или лишь переназначает свой локальный параметр?
Возврат объекта
- Метод может вернуть ссылку на объект — тогда вызывающий код разделяет его.
public Student topStudent() { return best; }возвращает ссылку наbest. - Возврат
bestделит один и тот же существующий объект. В отличие от него,return new Student("Copy");создает новый объект и возвращает ссылку на него; метод также может вернутьnull. Прочтите выражение возврата перед тем, как решать, является ли состояние общим.
Скопированная ссылка, общий объект; скопированное примитивное значение
Оценка объекта меняется; примитив x — нет.
При передаче объекта методу, метод получает...
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Java копирует значение ссылки в отдельную переменную параметра. Обе ссылки могут указывать на один и тот же объект; переназначение параметра не заменяет переменную вызывающего кода.
Метод может изменить переменную int вызывающей стороны, изменив ее параметр.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Примитивы копируются — переменная int вызывающей стороны остается нетронутой.
Вызов экземплярного метода через null-ссылку вызывает исключение...
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
null указывает на отсутствие объекта, поэтому не к чему вызывать метод.
Метод может возвращать ссылку на объект, которую затем использует вызывающий код.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Метод может вернуть существующую ссылку на объект и разделить его с вызывающим кодом. Другой метод может создать и вернуть новый объект.
Чтобы безопасно использовать ссылку, которая может быть null, следует сначала проверить...
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Проверьте наличие null перед вызовом метода.
Каждый метод, возвращающий ссылку на Student, должен возвращать ранее существующий объект.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Ложь: return new Student("Other"); создает и возвращает новый объект.
Нулевая ссылка
- Ссылка, указывающая на ни один объект, называется
null. Вызов экземплярного метода черезnullвызывает NullPointerException. - Возврат
null(например, «не найдено») встречается часто — вызывающий код должен проверять наличие такого значения. Используйте проверку наif (s != null) { s.addScore(10); }перед использованием ссылки, которая может быть пустой.
Передача объекта копирует значение ссылки — метод может изменить объект вызывающего кода; передача примитива копирует значение — он не может. Таким образом, student.addScore(10) мутирует объект вызывающего кода, но changeInt(x) оставляет x вызывающего кода нетронутым. Вызов экземплярного метода через ссылку null вызывает NullPointerException — проверяйте != null первым делом, если ссылка может быть пустой.
After the two statements, what is the original caller-referenced Student score?
Сложность 2/5 · 140 монет + небольшой бонус за первое выполнение сегодня
The first statement mutates the original object to 15. The later local reassignment does not replace the caller reference.
Метод возвращает new Student("Other"); но вызывающий код игнорирует результат. Что происходит со существующей переменной Student у вызывающего кода?
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Возврат ссылки не присваивает её переменной вызывающего кода. Существующая переменная по-прежнему указывает на свой исходный объект.
Ссылка против значения:
void addTen(Student s) { s.addScore(10); }— изменяет переданный объект (разделенная ссылка).void addTen(int x) { x += 10; }— переменная вызывающего кодаintостается неизменной (скопированное значение).- Оба значения параметров копируются; только скопированная ссылка достигает общего изменяемого состояния.
Перенесите рассуждения на новый случай
- Сравните
return s;сreturn new Student("Other");: первое возвращает переданную ссылку; второе возвращает Newly constructed object. Ни один из возвратов не изменяет переменную вызывающего кода до тех пор, пока вызывающий код не присвоит результат. - Чтобы предсказать изменение, нарисуйте вызывающий код и параметр как отдельные переменные-ссылки, указывающие на объекты. Обновите объект при вызове мутатора и обновите только стрелку параметра при переназначении параметра.
Передача ссылки на объект копирует её значение в параметр, поэтому метод может изменить объект вызывающего кода; передача примитива копирует значение, поэтому он не может. Метод может вернуть ссылку на объект. Ссылка ни на один объект — это null — вызов экземплярного метода через неё вызывает NullPointerException, поэтому сначала нужно проверить.