這一節我們來說說構造函數在內存中是如何被加載的。
我們之前說過,構造函數只有創建對象時才會被調用并且只調用一次。那么在創建對象的過程中內存中的變化是什么樣的呢?
我們接著上一節的Person類,我們分析
~~~
class Person
{
private String name;
private int age;
Person()//構造函數,分別為成員變量name和age賦固定的值
{
name = "baby";
age = 1;
System.out.println("person run");
}
Person(String n)//構造函數,有一個初始name參數
{
name = n;
}
Person(String n,int a)
{
name = n;
age = a;
}
public void speak()
{
System.out.println(name+":"+age);
}
}
~~~
我們用下面的兩行代碼來分析一下構造函數在內存中的加載過程
~~~
class ConsDemo
{
public static void main(String[] args)
{
Person p = new Person("小強",10);
p.speak();
}
}
~~~
對于上面的測試,我們分析它的運行過程:
1.main方法進棧內存,main方法中有一個Person類類型變量p;
2.new創建Person對象,在堆內存中創建空間(假如地址為0x0045),該空間中有兩個成員變量name和age;
3.對對象的兩個成員變量進行初始化,此時會自動選擇調用構造函數Person(String n,int a);
4.構造函數Person(String n,int a)進棧內存,并且有參數n="小強",a=0;
5.然后在堆內存中把參數n和a的數值初始化name和age變量,此時對象的初始化完成;
6.把地址0x0045賦給main方法中的變量p;
7.構造函數Person()出棧,釋放參數n和a;
8.執行p.speak()語句,調用Person類中的speak()方法,則speak方法進棧;
9.執行打印語句,跳出speak方法,speak方法出棧;
10.跳出main方法,main方法出棧,程序運行結束。
我們在上面通過對一個簡單的對象創建過程進行了分析,簡單的學習了構造函數在內存中的加載和運行過程,這里也就是突出了對象的初始化,如果類中沒有定義構造函數,那么我們在創建對象時會調用默認的構造函數,而當我們定義了構造函數,則會通過參數類型選擇不同的構造函數進行對象的初始化,而且我們知道對象都必須被初始化,初始化就會調用相應的構造函數,所以說,構造函數是必須會進棧內存的。
- 前言
- 1.1 基本常識
- 1.2 Java語言概述
- 1.3 Java語言的環境搭建
- 1.4 Java程序開發之初體驗--Hello World
- 2.1 關鍵字
- 2.2 標識符
- 2.3 注釋
- 2.4 常量
- 2.5 進制掃盲
- 2.6 變量和數據類型(1)
- 2.7 變量和數據類型(2)
- 2.8 運算符
- 3.1 if語句
- 3.2 switch語句
- 3.3 while和do-while語句
- 3.4 for語句
- 3.5 for循環的嵌套
- 3.6 break語句與continue語句
- 4.1 函數的定義
- 4.2 定義函數的兩個明確
- 4.3 函數的內存加載過程
- 4.4 函數的重載
- 5.1 數組的定義
- 5.2 數組的內存分配及特點
- 5.3 數組操作中常見問題
- 5.4 數組常用操作(1)
- 5.5 數組常用操作(2)
- 5.6 二維數組
- 6.1 面向對象的概述
- 6.2 類與對象的關系
- 6.3 對象的內存體現
- 6.4 成員變量與局部變量
- 6.5 類類型參數與匿名對象
- 6.6 基本數據類型參數與引用數據類型參數的傳遞過程
- 6.7 封裝
- 7.1 構造函數概述與默認構造函數
- 7.2 構造函數與一般函數的區別
- 7.3 構造函數的重載
- 7.4 構造函數的內存加載
- 7.5 構造函數需要注意的幾個細節
- 7.6 this關鍵字的原理
- 7.7 this關鍵字的細節與應用
- 8.1 static關鍵字之特點
- 8.2 成員變量與靜態變量的區別
- 8.3 static關鍵字使用的注意細節
- 8.4 main函數的解析與細節
- 8.5 static關鍵字的使用場景
- 8.6 靜態的內存加載
- 8.7 靜態代碼塊
- 8.8 構造代碼塊
- 9.1 繼承
- 9.2 單繼承與多重繼承
- 9.3 子父類中成員變量特征體現