Раньше мы использовали концепцию «объекта», но не обсуждали конкретный способ хранения объектов в памяти. Это обсуждение приведет к важной концепции «ссылки на объект».
ссылка на объект
Мы продолжаем использовать определенный ранее класс Human и имеем класс Test:
Скопируйте код кода следующим образом:
тест публичного класса
{
public static void main(String[] args)
{
Человек aPerson = новый Человек(160);
}
}
классЧеловеческий
{
/**
* конструктор
*/
общественный человек (int h)
{
this.height = ч;
}
/**
*аксессуар
*/
публичный int getHeight()
{
вернуть this.height;
}
/**
* мутатор
*/
public voidrowHeight(int h)
{
this.height = this.height + h;
}
частная высота int;
}
Классы можно вызывать извне для создания объектов, как показано выше в классе Test:
Скопируйте код кода следующим образом:
Человек aPerson = новый Человек(160);
Создается объект класса Человек Человека.
Вышеупомянутое утверждение очень простое, но нам нужно углубиться в множество деталей:
1. Сначала посмотрите на правую часть знака равенства. new открывает место для объектов в памяти. В частности, new открывает место для объектов в куче памяти. В этом пространстве хранятся данные и методы объекта.
2. Посмотрите на левую часть знака равенства. aPerson ссылается на объект Human, который называется ссылкой на объект. Фактически aPerson не является самим объектом, а похож на указатель на объект. aPerson существует в стеке в памяти.
3. Когда мы используем знак равенства для присвоения значения, адрес объекта, созданного в куче с помощью new справа, присваивается ссылке на объект.
Под памятью здесь понимается пространство памяти процесса Java, виртуализированное JVM (виртуальной машиной Java). Понятия кучи и стека в памяти можно найти в книге Linux From Program to Process.
Стек можно прочитать быстрее, чем кучу, но данные, хранящиеся в стеке, ограничены допустимым диапазоном. В языке C, когда вызов функции завершается, соответствующий кадр стека удаляется, а параметры и автоматические переменные, хранящиеся в кадре стека, исчезают. Стек Java также подвергается такому же ограничению. Когда вызов метода завершается, данные, хранящиеся в стеке этим методом, будут очищены. В Java все (обычные) объекты хранятся в куче. Следовательно, полный смысл ключевого слова new заключается в создании объекта в куче.
Объекты примитивных типов, таких как int и double, хранятся в стеке. Когда мы объявляем базовый тип, нет необходимости в новом. После объявления Java сохраняет примитивные типы данных непосредственно в стеке. Таким образом, имя переменной базового типа представляет собой сами данные, а не ссылку.
Отношения между ссылками и объектами подобны воздушному змею и человеку. Когда мы смотрим на небо (прописано в программе), мы видим воздушного змея (эталон), а воздушному змею соответствует человек (объект):
Разделение ссылок и объектов ссылки указывают на объекты;
Хотя ссылки и объекты разделены, весь наш доступ к объектам должен проходить через «дверь» ссылок, например, доступ к методам объекта через reference.method(). В Java мы не можем пропускать ссылки и напрямую касаться объектов. Другой пример: если элемент данных объекта a является обычным объектом b, элемент данных a сохраняет ссылку на объект b (если это переменная базового типа, то элемент данных a сохраняет саму переменную базового типа). .
В Java ссылки играют роль указателей, но мы не можем напрямую изменять значение указателя, например добавлять 1 к значению указателя, как в языке C. Мы можем выполнять операции с объектами только через ссылки. Такая конструкция позволяет избежать многих ошибок, которые могут вызвать указатели.
справочное задание
Когда мы присваиваем ссылку другой ссылке, мы фактически копируем адрес объекта. Обе ссылки будут указывать на один и тот же объект. Например, dummyPerson=aPerson приведет к следующему:
Объект может иметь несколько ссылок (один человек может запускать несколько воздушных змеев). Когда программа изменяет объект по одной ссылке, это изменение видно по другим ссылкам. Мы можем использовать следующий класс Test для проверки фактического эффекта:
Скопируйте код кода следующим образом:
тест публичного класса
{
public static void main(String[] args)
{
Человек aPerson = новый Человек(160);
Человек-манекенЧеловек = Человек;
System.out.println(dummyPerson.getHeight());
aPerson.growHeight(20);
System.out.println(dummyPerson.getHeight());
}
}
Наши изменения в aPerson повлияют на dummyPerson. Эти две ссылки фактически указывают на один и тот же объект.
Таким образом, присвоение ссылки другой ссылке не копирует сам объект. Мы должны найти другие механизмы для копирования объектов.
Сбор мусора
По завершении вызова метода переменные ссылочного и примитивного типа очищаются. Поскольку объект находится в куче, память, занятая объектом, не будет очищена после завершения вызова метода. Пространство процесса может быстро заполниться создаваемыми объектами. Java имеет встроенный механизм сбора мусора для очистки объектов, которые больше не используются, для освобождения пространства памяти.
Основной принцип сборки мусора заключается в том, что при наличии ссылки, указывающей на объект, объект не будет переработан; при отсутствии ссылки, указывающей на объект, объект очищается; Занимаемое им пространство рекультивируется.
На рисунке выше предполагается состояние памяти в JVM в определенный момент. Объект Human имеет три ссылки: aPerson и dummyPerson из стека, а также President — член данных другого объекта. Объект Club не имеет ссылки. Если в это время начнется сбор мусора, объект «Клуб» будет очищен, а также будет удалена ссылка на объект «Человеческий» (президент) из объекта «Клуб».
Сбор мусора — важный механизм Java, который напрямую влияет на эффективность работы Java. Я расскажу об этом позже.
Передача параметров
Когда мы разделяем концепции ссылок и объектов, механизм передачи параметров методов Java на самом деле очень ясен: передача параметров Java осуществляется по значению. То есть, когда мы передаем параметр, метод получит копию параметра.
Фактически, один из передаваемых нами параметров — это переменная базового типа, а другой — ссылка на объект.
Передача по значению для переменных примитивного типа означает, что сама переменная копируется и передается методу Java. Модификации переменных методами Java не повлияют на исходные переменные.
Передача по значению означает, что адрес объекта копируется и передается методу Java. Доступ к методу Java на основе этой ссылки повлияет на объект.
Здесь стоит упомянуть еще одну ситуацию: мы используем new внутри метода для создания объекта и возврата ссылки на объект. Если возврат получен по ссылке, поскольку ссылка на объект не равна 0, объект все равно существует и не будет подвергаться сборке мусора.
Подвести итог
новый
ссылка, объект
Условия вывоза мусора
Параметры: передаются по значению