Что означает оператор new в java
Перейти к содержимому

Что означает оператор new в java

  • автор:

Creating Objects

As you know, a class provides the blueprint for objects; you create an object from a class. Each of the following statements taken from the CreateObjectDemo program creates an object and assigns it to a variable:

The first line creates an object of the Point class, and the second and third lines each create an object of the Rectangle class.

Each of these statements has three parts (discussed in detail below):

  1. Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
  2. Instantiation: The new keyword is a Java operator that creates the object.
  3. Initialization: The new operator is followed by a call to a constructor, which initializes the new object.

Declaring a Variable to Refer to an Object

Previously, you learned that to declare a variable, you write:

This notifies the compiler that you will use name to refer to data whose type is type. With a primitive variable, this declaration also reserves the proper amount of memory for the variable.

You can also declare a reference variable on its own line. For example:

If you declare originOne like this, its value will be undetermined until an object is actually created and assigned to it. Simply declaring a reference variable does not create an object. For that, you need to use the new operator, as described in the next section. You must assign an object to originOne before you use it in your code. Otherwise, you will get a compiler error.

A variable in this state, which currently references no object, can be illustrated as follows (the variable name, originOne , plus a reference pointing to nothing):

Instantiating a Class

The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the object constructor.

The new operator requires a single, postfix argument: a call to a constructor. The name of the constructor provides the name of the class to instantiate.

The new operator returns a reference to the object it created. This reference is usually assigned to a variable of the appropriate type, like:

The reference returned by the new operator does not have to be assigned to a variable. It can also be used directly in an expression. For example:

This statement will be discussed in the next section.

Initializing an Object

Here's the code for the Point class:

This class contains a single constructor. You can recognize a constructor because its declaration uses the same name as the class and it has no return type. The constructor in the Point class takes two integer arguments, as declared by the code (int a, int b). The following statement provides 23 and 94 as values for those arguments:

The result of executing this statement can be illustrated in the next figure:

Here's the code for the Rectangle class, which contains four constructors:

Each constructor lets you provide initial values for the rectangle's origin, width, and height, using both primitive and reference types. If a class has multiple constructors, they must have different signatures. The Java compiler differentiates the constructors based on the number and the type of the arguments. When the Java compiler encounters the following code, it knows to call the constructor in the Rectangle class that requires a Point argument followed by two integer arguments:

This calls one of Rectangle 's constructors that initializes origin to originOne . Also, the constructor sets width to 100 and height to 200. Now there are two references to the same Point object—an object can have multiple references to it, as shown in the next figure:

The following line of code calls the Rectangle constructor that requires two integer arguments, which provide the initial values for width and height. If you inspect the code within the constructor, you will see that it creates a new Point object whose x and y values are initialized to 0:

The Rectangle constructor used in the following statement doesn't take any arguments, so it's called a no-argument constructor:

All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor ( Object does have one), the compiler will reject the program.

Что означает оператор new в java

When you are declaring a class in java, you are just creating a new data type. A class provides the blueprint for objects. You can create an object from a class. However obtaining objects of a class is a two-step process :

      Declaration : First, you must declare a variable of the class type. This variable does not define an object. Instead, it is simply a variable that can refer to an object. Below is general syntax of declaration with an example :

A variable in this state, which currently references no object, can be illustrated as follows (the variable name, mybox, plus a reference pointing to nothing):

The new operator is also followed by a call to a class constructor, which initializes the new object. A constructor defines what occurs when an object of a class is created. Constructors are an important part of all classes and have many significant attributes. In below example we will use the default constructor. Below is general syntax of instantiation and initialization with an example :

Before understanding, how new dynamically allocates memory, let us see class Box prototype.

A variable after second step, currently refer to a class object, can be illustrated as follows (the variable name, mybox, plus a reference pointing to Box object):

Hence declaration of a class variable, instantiation of a class and initialization of an object of class can be together illustrated as follows :

Important points :

  1. The above two statements can be rewritten as one statement.
  2. The reference returned by the new operator does not have to be assigned to a class variable. It can also be used directly in an expression. For example:
  3. Since arrays are object in java, hence while instantiating arrays, we use new operator. For example:
  4. At this point, you might be wondering why you do not need to use new operator for primitives data types. The answer is that Java’s primitive types are not implemented as objects. Rather, they are implemented as “normal” variables. This is done in the interest of efficiency. For object versions of the primitive data types, refer Wrapper Classes.
  5. The phrase “instantiating a class” means the same thing as “creating an object.” When you create an object, you are creating an “instance” of a class, therefore “instantiating” a class.

Assigning object reference variables

When you assign one object reference variable to another object reference variable, you are not creating a copy of the object, you are only making a copy of the reference. Let us understand this with an example.

Explanation :

First let us understand what the following fragment does in above program.

You might think that b2 is being assigned a reference to a copy of the object referred to by b1. That is, you might think that b1 and b2 refer to separate and distinct objects. However, this would be wrong. Instead, after this fragment executes, b1 and b2 will both refer to the same object. The assignment of b1 to b2 did not allocate any memory or copy any part of the original object. It simply makes b2 refer to the same object as does b1. Thus, any changes made to the object through b2 will affect the object to which b1 is referring, since they are the same object. Same can be verified by output when we change height of box via b2.

This situation can be illustrated as follows :

Note : Although b1 and b2 both refer to the same object, they are not linked in any other way. For example, a subsequent assignment to b1 will simply unhook b1 from the original object without affecting the object or affecting b2.For example :

Here, b1 has been set to null, but b2 still points to the original object.

Passing object references variables to methods

When we pass object reference to a method, the parameter that receives it will refer to the same object as that referred to by the argument. To know more with examples, refer Passing and Returning Objects in Java.

This article is contributed by Gaurav Miglani. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Creating and Using Objects

A typical Java program creates many objects, which as you know, interact by invoking methods. Through these object interactions, a program can carry out various tasks, such as implementing a GUI, running an animation, or sending and receiving information over a network. Once an object has completed the work for which it was created, its resources are recycled for use by other objects.

Here is a small program, called CreateObjectDemo , that creates three objects: one Point object and two Rectangle objects. You will need all three source files to compile this program.

Here is the Point class:

And the Rectangle class:

This program creates, manipulates, and displays information about various objects. Here's the output:

The following three sections use the above example to describe the life cycle of an object within a program. From them, you will learn how to write code that creates and uses objects in your own programs. You will also learn how the system cleans up after an object when its life has ended.

Creating Objects

As you know, a class provides the blueprint for objects; you create an object from a class. Each of the following statements taken from the CreateObjectDemo program creates an object and assigns it to a variable:

The first line creates an object of the Point class, and the second and third lines each create an object of the Rectangle class.

Each of these statements has three parts (discussed in detail below):

  1. Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
  2. Instantiation: The new keyword is a Java operator that creates the object.
  3. Initialization: The new operator is followed by a call to a constructor, which initializes the new object.

Declaring a Variable to Refer to an Object

Previously, you learned that to declare a variable, you write:

This notifies the compiler that you will use name to refer to data whose type is type. With a primitive variable, this declaration also reserves the proper amount of memory for the variable.

You can also declare a reference variable on its own line. For example:

If you declare originOne like this, its value will be undetermined until an object is actually created and assigned to it. Simply declaring a reference variable does not create an object. For that, you need to use the new operator, as described in the next section. You must assign an object to originOne before you use it in your code. Otherwise, you will get a compiler error.

A variable in this state, currently references no object.

Instantiating a Class

The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the object constructor.

Note: The phrase "instantiating a class" means the same thing as "creating an object." When you create an object, you are creating an "instance" of a class, therefore "instantiating" a class.

The new operator requires a single, postfix argument: a call to a constructor. The name of the constructor provides the name of the class to instantiate.

The new operator returns a reference to the object it created. This reference is usually assigned to a variable of the appropriate type, like:

The reference returned by the new operator does not have to be assigned to a variable. It can also be used directly in an expression. For example:

This statement will be discussed in the next section.

Initializing an Object

Here is the code for the Point class:

This class contains a single constructor. You can recognize a constructor because its declaration uses the same name as the class and it has no return type. The constructor in the Point class takes two integer arguments, as declared by the code (int a, int b) . The following statement provides 23 and 94 as values for those arguments:

The result of executing this statement can be illustrated in the next figure:

A Point Object

Here is the code for the Rectangle class, which contains four constructors:

Each constructor lets you provide initial values for the rectangle's origin , width , and height , using both primitive and reference types. If a class has multiple constructors, they must have different signatures. The Java compiler differentiates the constructors based on the number and the type of the arguments. When the Java compiler encounters the following code, it knows to call the constructor in the Rectangle class that requires a Point argument followed by two integer arguments:

This calls one of Rectangle 's constructors that initializes origin to originOne . Also, the constructor sets width to 100 and height to 200. Now there are two references to the same Point object—an object can have multiple references to it, as shown in the next figure:

A Rectangle Object

A Rectangle Object

The following line of code calls the Rectangle constructor that requires two integer arguments, which provide the initial values for width and height . If you inspect the code within the constructor, you will see that it creates a new Point object whose x and y values are initialized to 0:

The Rectangle constructor used in the following statement does not take any arguments, so it is called a no-argument constructor:

All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor ( Object does have one), the compiler will reject the program.

Using Objects

Once you have created an object, you probably want to use it for something. You may need to use the value of one of its fields, change one of its fields, or call one of its methods to perform an action.

Referencing an Object's Fields

Object fields are accessed by their name. You must use a name that is unambiguous.

You may use a simple name for a field within its own class. For example, we can add a statement within the Rectangle class that prints the width and height :

In this case, width and height are simple names.

Code that is outside the object's class must use an object reference or expression, followed by the dot ( . ) operator, followed by a simple field name, as in:

For example, the code in the CreateObjectDemo class is outside the code for the Rectangle class. So to refer to the origin , width , and height fields within the Rectangle object named rectOne , the CreateObjectDemo class must use the names rectOne.origin , rectOne.width , and rectOne.height , respectively. The program uses two of these names to display the width and the height of rectOne :

Attempting to use the simple names width and height from the code in the CreateObjectDemo class does not make sense — those fields exist only within an object — and results in a compiler error.

Later, the program uses similar code to display information about rectTwo . Objects of the same type have their own copy of the same instance fields. Thus, each Rectangle object has fields named origin , width , and height . When you access an instance field through an object reference, you reference that particular object's field. The two objects rectOne and rectTwo in the CreateObjectDemo program have different origin , width , and height fields.

To access a field, you can use a named reference to an object, as in the previous examples, or you can use any expression that returns an object reference. Recall that the new operator returns a reference to an object. So you could use the value returned from new to access a new object's fields:

This statement creates a new Rectangle object and immediately gets its height . In essence, the statement calculates the default height of a Rectangle . Note that after this statement has been executed, the program no longer has a reference to the created Rectangle , because the program never stored the reference anywhere. The object is unreferenced, and its resources are free to be recycled by the Java Virtual Machine.

Calling an Object's Methods

You also use an object reference to invoke an object's method. You append the method's simple name to the object reference, with an intervening dot operator ( . ). Also, you provide, within enclosing parentheses, any arguments to the method. If the method does not require any arguments, use empty parentheses.

The Rectangle class has two methods: getArea() to compute the rectangle's area and move() to change the rectangle's origin. Here's the CreateObjectDemo code that invokes these two methods:

The first statement invokes rectOne 's getArea() method and displays the results. The second line moves rectTwo because the move() method assigns new values to the object's origin.x and origin.y .

As with instance fields, objectReference must be a reference to an object. You can use a variable name, but you also can use any expression that returns an object reference. The new operator returns an object reference, so you can use the value returned from new to invoke a new object's methods:

The expression new Rectangle(100, 50) returns an object reference that refers to a Rectangle object. As shown, you can use the dot notation to invoke the new Rectangle 's getArea() method to compute the area of the new rectangle.

Some methods, such as getArea() , return a value. For methods that return a value, you can use the method invocation in expressions. You can assign the return value to a variable, use it to make decisions, or control a loop. This code assigns the value returned by getArea() to the variable areaOfRectangle :

In this case, the object that getArea() is invoked on is the rectangle returned by the constructor.

The Garbage Collector

Some object-oriented languages require that you keep track of all the objects you create and that you explicitly destroy them when they are no longer needed. Managing memory explicitly is tedious and error-prone. The Java platform allows you to create as many objects as you want (limited, of course, by what your system can handle), and you do not have to worry about destroying them. The Java runtime environment deletes objects when it determines that they are no longer being used. This process is called garbage collection.

An object is eligible for garbage collection when there are no more references to that object. References that are held in a variable are usually dropped when the variable goes out of scope. Or, you can explicitly drop an object reference by setting the variable to the special value null . Remember that a program can have multiple references to the same object; all references to an object must be dropped before the object is eligible for garbage collection.

The Java runtime environment has a garbage collector that periodically frees the memory used by objects that are no longer referenced. The garbage collector does its job automatically when it determines that the time is right.

Модуль 2. Урок 3. Работа с экземплярами в Java. — Введение в Java

Внимание. В слайде была ошибка. time: 01:48 в классе Main метод main должен быть void , а не voind .

В этом уроке много базовых терминов. Их нужно знать как алфавит. Вам придется неоднократно возвращаться и повторять этот материал — это нормально. 🙂

Java Virtual Machine (JVM) — это программная система, в которой исполняются java-программы. Для java-программ JVM является реальной, а не виртуальной вычислительной машиной. А вот уже JVM написана под различные платформы и операционные системы.

blueprint — буквально это "фотографическая копия раннего плана здания или машины". Выполняется на бумаге синего (голубого) цвета. В рамках программирования это тоже чертеж, на основании которого будет создан объект. Только этот чертеж состоит не из линий на чертежной доске, а из строк кода, которые задают свойства и возможности будущих объектов.

класс — это тот самый blueprint в мире java, по которому будут создаваться объекты. Класс состоит из кода, который хранится в соответствующем файле.

Вот пример кода класса Human, который должен обязательно находится в файле Human.java :

На основе этих строк будут создаваться объекты.

члены класса — это основные элементы, которые может содержать в себе класс. Ими являются переменные (поля) и методы.

экземпляр, объект, instance — это сущность созданная на основе класса. Так же как и деталь на токарном станке создается на основе чертежа или человек "создается" на основе ДНК. Например, объект класса Object создается так: new Object() . А объект класса Human — new Human() . В мире java все является объектом.

оператор new выделяет место в памяти JVM под объект.

идентификатор (ссылка на документацию) — это, по сути, имя. Такое же, как и у людей, мест, объектов во всем мире. Но в документации java применяется термин "identifier". Потому что он позволяет идентифицировать конкретную сущность в мире java. В java идентификатор используется для переменных, методов, классов. Например, Object, String, Human, SomeClassName — это примеры идентификаторов (имен) классов. Имена классов всегда пишутся с большой буквы в camelStyle. Имена методов мы разберем в отдельном уроке. А имена переменных — в этом.

метод — это член класса в котором описывается логика (последовательность действий) над данными. О методах мы поговорим в других уроках.

reference, ссылка, переменная — это идентификатор (имя), с заданным типом, который может указывать на конкретный объект в оперативной памяти или на значение примитива. Ссылку часто называют переменной, но это не всегда соответствует ее свойствам. Важно понимать, что любая переменная предназначена для хранения адреса в памяти на конкретный объект или значение примитива, потому — ссылка на что-то. Правила именования ссылок будут даны ниже. При объявлении ссылки, естественно, нужно указать ее тип и имя. Например, так: Object myObject . Object — это тип, который сможет хранить в себе данная ссылка. myObject — это имя. Но эта ссылка, пока что, указывает в никуда, в null . Ей нужно присвоить объект — инициализировать.

null — это специальное ключевое слово, которое означает буквально "ничто".

инициализация переменной — это присвоение ссылке адреса конкретного объекта. Делается это с помощью знака равно " = ". В java это оператор присваивания. Запишем объявление ссылки, ее инициализацию и создание объекта в одну строчку: Object otherObject = new Object(); .

На один и тот же объект могут ссылаться несколько ссылок:

В данном кусочке кода создан один объект типа Human и присвоен трем ссылкам (передан его адрес в памяти по цепочке). А вот если написать напротив каждой ссылки new Human() — то у каждой ссылки будет свой объект.

У одной ссылки (идентификатора) — может быть только один объект!

блок кода — это часть кода, заключенная в фигурные скобки: <> . < — открывает блок кода. >— закрывает блок кода. Класс, метод, цикл, условный оператор — имеют свои блоки кода. Блок кода каждого из них, для простоты, называют телами. Методы, циклы, условные операторы — мы рассмотрим в других уроках. А сейчас давайте просто посмотрим на их тела в таком примере:

Переменные (ссылки), согласно документации, делятся на такие типы:

  • Поля класса. Это ссылки, которые объявлены в теле класса. Если взять в пример класс Human, то его полями будут name и age . В классе Computer это будет поле с именем foo . Объявление и инициализация поля класса не может быть разбито на две строки в рамках тела класса! Например, нельзя написать так: «`java class Computer2 < String foo; // объявляем поле класса foo = "просто пример поля класса"; // безуспешно пытаемся его инициализировать, ошибка компиляции! >

Где, как и когда инициализировать поля класса — зависит от условий задачи, которую Вы решаете.

  • Локальные переменные. Это ссылки, которые объявлены в любом блоке кода, который вложен в тело класса. Если рассмотреть класс Computer , то в нем локальной переменной будет result , поскольку эта ссылка объявлена внутри тела метода computeSumm .
  • Параметры. Это ссылки, задающие начальное состояние блока кода. Например, у метода computeSumm есть свой параметр incomeArray , который имеет тип int[] . Параметры метода еще называют "аргументы метода". А вот number уже является параметром цикла for .

Любая переменная — это просто ссылка на конкретный объект или значение (примитив) в памяти компьютера.

область видимости — это границы, в которых доступны переменные для членов класса. Каждый блок кода видит переменные внешнего блока кода, но не видит содержимое внутренних блоков кода. Например, ссылка foo объявлена в теле класса Computer — она видна любым другим членам текущего класса и вложенным друг в друга блокам кода. То есть мы можем печатать переменную foo не только в методе printFoo , но и в методе computeSumm или даже в цикле for . А вот переменная (параметр метода computeSumm ) incomeArray — видна только в рамках тела этого метода. Это значит, что класс Computer не знает о существовании incomeArray . И метод printFoo , соответственно, тоже не знает о существовании переменной incomeArray . Зато все вложенные в метод computeSumm блоки кода (циклы, условные операторы и все, что мы туда засунем) могут обращаться к incomeArray и использовать эту переменную. Аналогичной по видимости incomeArray является переменная result . А переменная number видна только в рамках тела цикла for .

Правила именования ссылок переменных

  1. имя ссылки всегда пишется с маленькой буквы;
  2. в верблюжем стиле и слитно, если более одного слова в имени ссылки, например, theAdam ;
  3. константы пишутся в теле класса и ПОЛНОСТЬЮЗАГЛАВНЫМИБУКВАМИ с подчеркиванием между словами, например: double NUMBER_PI = 3,14 ;
  4. имена переменных могут начинаться с: a — z , _ , $ ;
  5. имена не могут начинаться с любого числа или точки;
  6. имена не могут содержать в себе # , : , / и прочих символов, но могут содержать числа (не в начале!);
  7. имена не могут состоять только из ключевого слова синтаксиса java или литерала; например, нельзя объявить int new; , но можно объявить int newCounter; ; нельзя объявить String true; , но можно объявить String someTrueString; ;
  8. в теле одного блока кода не может быть полей с одинаковыми идентификаторами (именами)! Это значит, что если мы уже объявили в теле класса Computer поле String foo , то второй раз уже не нужно писать String foo в теле этого класса. Но зная об области видимости мы смело можем объявить еще один раз String foo , например, в рамках тела метода. Попробуйте это прямо сейчас в коде. Экспериментируйте и внимательно изучайте вывод компилятора — он дает много подсказок об ошибках в коде.

Ссылка на перечень разновидностей литералов. Для начала, проще запомнить эти литералы, которые нельзя использовать как готовые имена: true , false , null .

Использование объектов

Объект можно создать только из ссылочного типа бесконечное количество раз (в пределах возможностей компьютера). Примитивные типы просто имеют уже конечный перечень значений, которые мы можем использовать, а создавать объекты на их основе примитивов — невозможно. Но есть "обертки" над примитивами, из которых можно создавать объекты. Обертки являются ссылочными типами данных (см. предыдущий урок).

Для начала рассмотрим пример создания объектов на основе класса Human . Изучите код:

Экспериментируйте с этим кодом. Покрутите его в IDEA. Только ж не забудьте еще написать класс Human. 😉

использование объекта — это любая форма взаимодействия с объектом. Например, обращение к его членам или передача объекта в качестве параметра (аргумента) метода.

Для обращения к объекту, почти всегда, необходимо имя его ссылки. Например, для обращения к одному из двух объектов класса Human нам нужно написать theAdam или theEve . А дальше мы можем получить доступ к членам этих объектов.

доступ к членам объектов осуществляется посредством обычной точки " . ". Точка говорит: "Раскрыть этот объект!". А за точкой нужно указать идентификатор нужного нам члена объекта.

Например, обратимся к полю name объекта theAdam и назначим ему нормальное имя: theAdam.name = "Adam"; . Так же можно поменять имя и для theEve : theEve.name = "Eve"; . Рассмотрим это чуть ниже в примерах.

Обратите внимание, что поле name ссылается на конкретные объекты класса String . А это значит, что мы можем получить доступ к членам и этого объекта! Например так: theAdam.name.length() . Рассмотрим это в коде:

Рассмотрим инициализацию переменной lengthOfName :

  1. обращаемся к объекту переменной theAdam ;
  2. "раскрыли" его точкой;
  3. обращаемся к полю name , который по сути есть ссылка на объект класса String ;
  4. "раскрыли" его точкой;
  5. а у любого объекта класса String есть метод length() , к которому мы и обратились; он вернет число символов в текущем объекте;
  6. записываем результат работы нашей цепочки вызовов в локальную переменную lengthOfName .

Для обращения к объекту не всегда необходимо использовать имя его ссылки. Например, мы можем создать объект и тут же передать его в какой-то метод, при этом не сохраняя адрес этого объекта в коде: System.out.println(new Human()) . И к его членам мы тоже можем обратиться. Рассмотрим в коде:

Как видно из этого примера, мы создали несколько объектов и ни одной ссылки на них. Так стоит поступать только и только тогда, когда мы точно знаем, что не станем повторно использовать один и тот же объект.

Что такое Human@1b6d3586 — это то, как JVM видит внутри себя конкретный объект класса Human . У каждого нового объекта будет свой адрес в памяти JVM на подобии Human@1b6d3586 .

В данном случае, у каждого нового объекта класса Human всегда поле name будет содержать "Oldman" , а age — 99. Потому что изначально в классе были "зашиты" эти параметры, для удобства примеров кода. В рабочем коде предопределять значения рекомендуется только КОНСТАНТАМ.

Жизненный цикл любого класса в Java

  • дизайн класса (design) — предварительная проектировка, до написания кода. Например, в UML-диаграмме;

Предварительное описание классов и его членов — является хорошей практикой!

  • имплементация класса (реализация класса в редакторе) — описываем класс в виде кода в файле с расширением *.java ;
  • использование класса — это создание объекта на его основе.

Жизненный цикл instances (объектов) класса

  • Создание (creation) в памяти нового instance, реального объекта, который создается на базе класса, например, так: new Human() . Но лучше сразу объявить ссылку и передать ей этот объект: Human human = new Human(); .
  • Жизнь (living)/использование instance. Любые манипуляции с объектом, например, human.age = 12; или System.out.println(human.age); .

Доступ к полям объекта осуществляется через точку. Точка раскрывает объект и позволят добраться к полям этого объекта.

  • releasing (освобождать, отпускать, сбрасывать) — отвязываем текущий объект от ссылки, например, так human = null; или так human = new Human(); . Суть в том, что ссылка human больше не ссылается на тот же объект;
  • уничтожение (removing) — объект удаляется из памяти мусорщиком, если на него не ссылается ни одной ссылки в текущей программе.

Итак, у класса есть три этапа жизненного цикла: design, implementation, usage. А у объектов их четыре: creation, living, releasing, removing.

Память и объекты

Мы еще будем детально рассматривать stack и heap в грядущих уроках про методы. А пока взглянем на это в общих чертах для общего понимания. Ведь объекты эти существуют не в вакууме.

JVM разделяет свою память на stack & heap(куча). Стек служит для обеспечения работы методов. У каждой программы, у каждого потока свой стек. В стеке создаются фреймы вызываемых методов. А куча служит для хранения и доступа к объектам (одна куча на всю программу). Для простоты понимания:

  • Стек удобно рассматривать как стопку монет, в которой каждая монета — это запущенный метод. Так называемый "фрейм метода". Пока не отработает верхняя монета — остальные недоступны. Работает стек по принципу LIFO. Повторюсь: детальнее рассмотрим это в другом уроке.
  • Куча хоть и говорящее название, но эту область памяти JVM лучше воспринимать как библиотеку или склад, в которой каждая книжка имеет свой адрес.

Примитивы хранятся как в стеке, так и в хипе. Это зависит от места их объявления: в методе или на уровне класса. А объекты ссылочных типов хранятся только в хипе.

Рассмотрим такой пример:

someNumber — эта ссылка находится в фрейме метода main , а фрейм в стеке. И память под значение 999999 тоже выделена в стеке, в фрейме текущего метода.

human — эта ссылка находится в стеке метода main . О стеке методов, повторюсь, мы узнаем больше в следующих уроках. И указывает human на адрес в хипе, где находится экземпляр (инстанс) класса Human .

Сам объект human содержит в себе еще две ссылки: name типа String и age типа int . В строчках human.age = 12; и human.name = "Testor"; мы присваиваем этим ссылкам конкретные объекты.

В хипе это выглядит так:

  1. Для int age значение хранится в пределах объекта human , а сам объект в хипе.
  2. Для String name значение хранится где-то в хипе, так же как и human . Может даже в соседнем регистре памяти JVM. А в пределах объекта human просто записан адрес объекта в поле name . Поскольку тип String является ссылочным типом, а не примитивом.

Рекомендация

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

Именно эксперименты над кодом позволяют компенсировать недопонимание чего-либо в программировании. И в работе это приходиться делать частенько.

Полезные ссылки

Для более глубокого понимания, того как объекты занимают память, рекомендую прочитать вот эту статью.

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете
  • Статья «Как учиться и справляться с негативными мыслями»
  • Статья «Ловушки обучения»
  • Статья «Сложные простые задачи по программированию»
  • Урок «Как эффективно учиться на Хекслете»
  • Вебинар «Как самостоятельно учиться»

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *