Java Language
Ссылки на объекты
Это должно помочь вам понять «Исключение Null Pointer» — один получает один из них, потому что ссылка на объект имеет значение null, но программный код ожидает, что программа что-то использует в этой ссылке на объект. Тем не менее, это заслуживает своей темы .
Ссылки на объекты как параметры метода
В этом разделе объясняется концепция ссылки на объект ; он ориентирован на людей, которые новичок в программировании на Java. Вы уже должны быть знакомы с некоторыми терминами и значениями: определение класса, основной метод, экземпляр объекта и вызов методов «на» объекта и передача параметров методам.
public class Person < private String name; public void setName(String name) < this.name = name; >public String getName() < return name; >public static void main(String [] arguments) < Person person = new Person(); person.setName("Bob"); int i = 5; setPersonName(person, i); System.out.println(person.getName() + " " + i); >private static void setPersonName(Person person, int num) < person.setName("Linda"); num = 99; >>
Чтобы быть полностью компетентным в программировании на Java, вы должны уметь объяснить этот пример кому-то еще с головы. Его концепции имеют фундаментальное значение для понимания того, как работает Java.
Как вы можете видеть, у нас есть main задача, которая создает объект для person переменной и вызывает метод для установки поля name в этом объекте на «Bob» . Затем он вызывает другой метод и передает person как один из двух параметров; другой параметр представляет собой целочисленную переменную, установленную в 5.
Метод , называемый задает name значение на пройденный объекта к «Линде», и устанавливает целочисленную переменную передается до 99, а затем возвращается.
Итак, почему внесение изменений в person вступает в силу в main , но изменение, внесенное в целое число, не так ли?
Когда вызов выполняется, основной метод передает ссылку объекта для person методу setPersonName ; любое изменение, которое setAnotherName делает для этого объекта, является частью этого объекта, и поэтому эти изменения остаются частью этого объекта при возврате метода.
Другой способ сказать одно и то же: person указывает на объект (хранится в куче, если вам интересно). Любое изменение метода делает для этого объекта «на этом объекте» и не зависит от того, активен или вернулся метод внесения изменения. Когда метод возвращается, любые изменения, внесенные в объект, все еще сохраняются на этом объекте.
Сравните это с целым числом, которое передается. Поскольку это примитивный int (а не экземпляр объекта Integer), он передается «по значению», то есть его значение предоставляется методу, а не указателю на исходное целое число, переданное в. Метод может изменить его для метода собственных целей, но это не влияет на переменную, используемую при вызове метода.
В Java все примитивы передаются по значению. Объекты передаются по ссылке, что означает, что указатель на объект передается как параметр любым методам, которые их принимают.
Еще одна очевидная вещь: это означает, что вызываемый метод не может создать новый объект и вернуть его в качестве одного из параметров. Единственный способ для метода вернуть объект, который создается, прямо или косвенно, вызовом метода, является возвращаемым значением из метода. Давайте сначала посмотрим, как это не сработает, и как это будет работать.
Давайте добавим еще один способ к нашему маленькому примеру:
private static void getAnotherObjectNot(Person person)
И, вернувшись в main , под вызовом setAnotherName , давайте перейдем к этому методу и другому вызову println:
getAnotherObjectNot(person); System.out.println(person.getName());
Теперь программа распечатает:
Что случилось с объектом, в котором был Джордж? Ну, параметр, который был передан, был указателем на Линду; когда метод getAnotherObjectNot создал новый объект, он заменил ссылку на объект Linda ссылкой на объект George. Объект Линда все еще существует (в куче), main метод все равно может получить к нему доступ, но метод getAnotherObjectNot после этого не сможет ничего с ним сделать, потому что он не имеет к нему ссылки. Похоже, что автор кода, предназначенный для метода, создавал новый объект и передавал его обратно, но если это так, это не сработало.
Если это то, что хотел сделать автор, ему нужно было бы вернуть вновь созданный объект из метода, примерно так:
private static Person getAnotherObject()
Person mary; mary = getAnotherObject(); System.out.println(mary.getName());
И весь выпуск программы теперь будет:
Вот и вся программа с двумя дополнениями:
public class Person < private String name; public void setName(String name) < this.name = name; >public String getName() < return name; >public static void main(String [] arguments) < Person person = new Person(); person.setName("Bob"); int i = 5; setPersonName(person, i); System.out.println(person.getName() + " " + i); getAnotherObjectNot(person); System.out.println(person.getName()); Person person; person = getAnotherObject(); System.out.println(person.getName()); >private static void setPersonName(Person person, int num) < person.setName("Linda"); num = 99; >private static void getAnotherObjectNot(Person person) < person = new Person(); person.setMyName("George"); >private static person getAnotherObject() < Person person = new Person(); person.setMyName("Mary"); return person; >>
- Начало работы с Java Language
- 2D-графика в Java
- Apache Commons Lang
- API Reflection
- API стека
- AppDynamics и TIBCO BusinessWorks для легкой интеграции
- Autoboxing
- BigDecimal
- BigInteger
- BufferedWriter
- ByteBuffer
- CompletableFuture
- Enum, начиная с номера
- FileUpload для AWS
- FTP (протокол передачи файлов)
- HttpURLConnection
- InputStreams и OutputStreams
- Java Pitfalls — использование исключений
- Java Pitfalls — синтаксис языка
- JavaBean
- Java-агенты
- Java-версии, версии, выпуски и дистрибутивы
- JAXB
- JAX-WS
- JMX
- JNDI
- JShell
- JSON в Java
- LinkedHashMap
- log4j / log4j2
- NIO — Сеть
- NumberFormat
- ServiceLoader
- SortedMap
- Streams
- StringBuffer
- StringBuilder
- sun.misc.Unsafe
- ThreadLocal
- TreeMap и TreeSet
- Varargs (переменный аргумент)
- WeakHashMap
- XJC
- XOM — Объектная модель XML
- Альтернативные коллекции
- Анализ XML с использованием API JAXP
- Аннотации
- Апплеты
- Атомные типы
- аудио
- Безопасность и криптография
- Безопасность и криптография
- Бит-манипуляция
- Валюта и деньги
- Ведение журнала (java.util.logging)
- Видимость (контроль доступа к членам класса)
- Виртуальная машина Java (JVM)
- Виртуальный доступ Java
- Вложенные и внутренние классы
- Возможности Java SE 7
- Возможности Java SE 8
- Выбор коллекций
- Выражения
- Генерация случайных чисел
- Геттеры и сеттеры
- Даты и время (java.time. *)
- Двигатель JavaScript Nashorn
- Дженерики
- Документирование кода Java
- Загрузчики классов
- Защищенные объекты
- Изменение байтового кода
- Инкапсуляция
- Интерфейс Dequeue
- Интерфейс Java Native
- Интерфейс инструмента JVM
- Интерфейсы
- Исключения и обработка исключений
- Исполнители, Исполнительные службы и пулы потоков
- Использование ThreadPoolExecutor в приложениях MultiThreaded.
- Использование других языков сценариев в Java
- Использование ключевого слова static
- Итератор и Итерабель
- Календарь и его подклассы
- Карта Enum
- Карты
- Класс — отражение Java
- Класс EnumSet
- Класс java.util.Objects
- Класс даты
- Класс свойств
- Классы и объекты
- Клонирование объектов
- Кодировка символов
- Коллекции
- Команда Java — «java» и «javaw»
- Команды выполнения
- Компилятор Java — «javac»
- Компилятор Just in Time (JIT)
- Консольный ввод-вывод
- Конструкторы
- литералы
- Локализация и интернационализация
- Лямбда-выражения
- Массивы
- Менеджер по безопасности
- Местное время
- Местный внутренний класс
- Методы и конструкторы классов объектов
- Методы по умолчанию
- Методы сбора коллекции
- Модель памяти Java
- Модификаторы без доступа
- Модули
- наборы
- наследование
- Настройка производительности Java
- Неизменяемые объекты
- Неизменяемый класс
- Необязательный
- Новый ввод-вывод файлов
- Обработка аргументов командной строки
- Общие ошибки Java
- Одиночки
- операторы
- Операции с плавающей точкой Java
- Ориентиры
- Основные управляющие структуры
- Отправка динамического метода
- Оценка XML XPath
- Очереди и Deques
- Ошибки Java — Nulls и NullPointerException
- Ошибки Java — потоки и параллелизм
- Ошибки Java — проблемы с производительностью
- пакеты
- Параллельное программирование (темы)
- Параллельное программирование с использованием структуры Fork / Join
- Параллельные коллекции
- Перечисления
- Полиморфизм
- предпочтения
- Преобразование в строки и из них
- Преобразование типа
- Примитивные типы данных
- Процесс
- Путь Класса
- Разборка и декомпиляция
- Развертывание Java
- Разделение строки на части с фиксированной длиной
- Реализации Java-плагинов
- Регулярные выражения
- Рекурсия
- Ресурсы (на пути к классам)
- Розетки
- Свободный интерфейс
- Сериализация
- сетей
- сканер
- Служба печати Java
- Создание изображений программно
- Создание кода Java
- Сокеты Java
- Списки
- Список против SET
- Сравнение C ++
- Сравнительный и компаратор
- Ссылки на объекты
- Стандарт официального кода Oracle
- Строковый токенизатор
- Струны
- супер ключевое слово
- Тестирование устройства
- Типы ссылок
- Типы ссылочных данных
- Удаленный вызов метода (RMI)
- Управление памятью Java
- Установка Java (стандартная версия)
- Утверждая
- Файловый ввод-вывод
- Файлы с несколькими релизами JAR
- Флаги JVM
- Функциональные интерфейсы
- Хеш-таблица
- Читатели и писатели
- Шифрование RSA
Java передать ссылку класс
Объекты классов, как и данные примитивных типов, могут передаваться в методы. Однако в данном случае есть одна особенность — при передаче объектов в качестве значения передается копия ссылки на область в памяти, где расположен этот объект. Рассмотрим небольшой пример. Пусть у нас есть следующий класс Person:
public class Program < public static void main(String[] args) < Person kate = new Person("Kate"); System.out.println(kate.getName()); // Kate changeName(kate); System.out.println(kate.getName()); // Alice >static void changeName(Person p) < p.setName("Alice"); >> class Person < private String name; Person(String name)< this.name = name; >public void setName(String name) < this.name = name; >public String getName() < return this.name; >>
Здесь в метод changeName передается объект Person, у которого изменяется имя. Так как в метод будет передаваться копия ссылки на область памяти, в которой находится объект Person, то переменная kate и параметр p метода changeName будут указывать на один и тот же объект в памяти. Поэтому после выполнения метода у объекта kate, который передается в метод, будет изменено имя с «Kate» на «Alice».
От этого случая следует отличать другой случай:
public class Program < public static void main(String[] args) < Person kate = new Person("Kate"); System.out.println(kate.getName()); // Kate changePerson(kate); System.out.println(kate.getName()); // Kate - изменения не произошло // kate хранит ссылку на старый объект >static void changePerson(Person p) < p = new Person("Alice"); // p указывает на новый объект p.setName("Ann"); >static void changeName(Person p) < p.setName("Alice"); >> class Person < private String name; Person(String name)< this.name = name; >public void setName(String name) < this.name = name; >public String getName() < return this.name; >>
В метод changePerson также передается копия ссылки на объект Person. Однако в самом методе мы изменяем не отдельные значения объекта, а пересоздаем объект с помощью конструктора и оператора new. В результате в памяти будет выделено новое место для нового объекта Person, и ссылка на этот объект будет привоена параметру p:
static void changePerson(Person p) < p = new Person("Alice"); // p указывает на новый объект p.setName("Ann"); // изменяется новый объект >
То есть после создания нового объекта Person параметр p и переменная kate в методе main будут хранить ссылки на разные объекты. Переменная kate, которая передавалась в метод, продолжит хранить ссылку на старый объект в памяти. Поэтому ее значение не меняется.