欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java創(chuàng)建對象之顯示創(chuàng)建與隱式創(chuàng)建

 更新時間:2023年05月12日 09:27:43   作者:一一哥Sun  
在本篇文章中,小編會帶大家學習面向?qū)ο笾嘘P(guān)于對象的創(chuàng)建之顯示創(chuàng)建和隱式創(chuàng)建,其實類和對象作為面向?qū)ο笾凶罨镜?,也是最重要?需要的朋友可以參考下

一. 對象簡介

1. 概念

在之前的文章中,其實已經(jīng)給大家解釋過對象的概念了。在面向?qū)ο蟮木幊桃?guī)范中,“一切皆對象”,對象就是面向?qū)ο缶幊痰暮诵摹,F(xiàn)實世界中的每一個物體都是對象!當然,這個“對象”不是你懷里撒嬌的男/女朋友,而是指某個“類”的一個實例。

比如,“人”是一個“整體”的概念,它不是“個體”的概念,所以“人”是“類別(模板)”,而不是對象。但是在人這個“類別”中,有法外狂徒張三這個個體,張三就是一個具體的“對象”。每個對象都有自己的狀態(tài)和行為,比如張三的狀態(tài)有:身高、體重、愛好;行為有:吃、喝、piao、du、抽,坑、蒙、拐、騙、偷等。

2. 行為和特征

一個對象主要包括行為和特征(狀態(tài)、屬性)兩個核心要素。

行為:一般是動詞,指的是方法,代表一個對象能干什么,具有哪些功能或能力,例如人可以吃飯、睡覺、說話、工作等;在Java中,一般是用方法來表明對象所具有的行為。

特征:也可以叫做狀態(tài),一般是名詞,指的是屬性,代表一個對象有什么特點或參數(shù),例如每個人的姓名、年齡、性別、體重等。在Java中,一般是用變量來表明對象的狀態(tài)。

3. 對象的創(chuàng)建方式(重點)

對象就是類的實例化,也就是根據(jù)類來創(chuàng)建一個具體的對象,就好比我們使用一個手機殼模具制造出一個具體的手機殼。接下來就給大家講一下,在Java中創(chuàng)建對象的兩種主要方式:顯式創(chuàng)建與隱式創(chuàng)建。

3.1 顯式創(chuàng)建

其中顯式創(chuàng)建對象時,又有以下4種具體的創(chuàng)建方式:

  • 使用new關(guān)鍵字創(chuàng)建對象;
  • 使用newlnstance()實例方法創(chuàng)建對象;
  • 使用clone()方法創(chuàng)建對象;
  • 使用ObjectlnputStream對象的readObject()方法創(chuàng)建對象。

3.2 隱式創(chuàng)建

隱式創(chuàng)建對象主要是包括以下幾種方式:

  • 給String字符串變量賦值;
  • “+”號拼接多個字符串;
  • JVM虛擬機加載類時隱式創(chuàng)建類對象。

接下來分別給大家講解一下這幾種創(chuàng)建對象的方式。受限于篇幅,今天主要是給大家講解通過new關(guān)鍵字創(chuàng)建對象的方式,其他的方式我們以后再細講。

二. 顯式創(chuàng)建

1. 使用new關(guān)鍵字創(chuàng)建對象

1.1 new簡介

我們知道,new是"新的"的意思。在Java中,new是一個關(guān)鍵字,它用于創(chuàng)建一個新的類實例,即新的類對象。所以在Java中,創(chuàng)建新對象也可以叫做實例化對象。 對于引用類型來說,如果該類型沒有進行實例化,也就是沒有進行對象的創(chuàng)建,那么該對象的屬性、方法等在內(nèi)存中都是不存在的。只有使用new關(guān)鍵字創(chuàng)建了對象之后,這個對象在內(nèi)存中才會存在,才能使用。

1.2 new作用

當一個引用類型的變量被聲明以后,如果沒有進行初始化,那么它就不指向任何對象,我們也就沒辦法使用該變量。所以我們就可以通過new關(guān)鍵字對該變量進行初始化,具體地來說,new關(guān)鍵字的作用如下:

  • 為新對象及對象中的各實例變量分配內(nèi)存空間;
  • 將新對象中的各實例變量自動初始化成對應類型的默認值;
  • 初始化對象,并給各實例變量賦予正確的初始值;
  • 調(diào)用引用類型對應的構(gòu)造方法;
  • 返回對象的引用。

1.3 基本語法

new關(guān)鍵字創(chuàng)建對象的語法格式如下:

類名 對象名 = new 類名();

1.4 代碼案例

為了讓大家更好地理解new的用法,給大家設(shè)計了如下代碼案例。

/**
 * @author 
 */
public class Demo01 {
    public static void main(String[] args) {
	// new關(guān)鍵字
	Person p1 = new Person();
    }
}

在這段簡單的代碼中,Person p1=new Person();,前半部分Person p1,表示是在內(nèi)存中分配一個Person類型的變量p1。后半部分new Person();,表示利用new關(guān)鍵字和構(gòu)造方法來創(chuàng)建一個Person類型的對象,Person()是構(gòu)造方法的名字。當構(gòu)造方法執(zhí)行完,這個Person類型的對象就建造出來了,也就為其分配了對應的內(nèi)存。

雖然p1是引用類型的變量,但p1自身會存儲在棧內(nèi)存中。而使用new關(guān)鍵字創(chuàng)造出來的對象,則被存儲在堆內(nèi)存(heap)中。且在new關(guān)鍵字真正創(chuàng)建出引用類型的對象之后,會把這個對象在內(nèi)存中的地址返回給p1變量進行引用,這樣我們就可以通過調(diào)用p1找到對內(nèi)存中的Person對象。

所以Person p1=new Person();這行代碼的作用就是,把Person對象在內(nèi)存中的地址 賦值 給變量p1。在Java中,我們可以把p1變量叫做引用變量,或者簡稱為引用。又因為p1變量中存放的是引用類型的內(nèi)存地址值,我們也可以把p1的值叫做引用地址。

2. newlnstance()方法

除了使用new關(guān)鍵字創(chuàng)建對象之外,我們還可以使用newInstance()方法創(chuàng)建對象。該方法是java.lang.Class 或 java.lang.reflect.Constuctor類中的實例方法,其語法格式如下:

java.lang.Class 類對象名稱 = java.lang.Class.forName(要實例化的類全稱);

類名 對象名 = (類名)Class類對象名稱.newInstance();

我們在調(diào)用java.lang.Class類中的forName()方法時,需要將待實例化類的全限定名(如 com.yyg.Person)作為參數(shù)傳遞進來,然后再調(diào)用 java.lang.Class類對象的newInstance()方法創(chuàng)建對象。

/** 
 * @author 
 */
public class Demo01 {
    public static void main(String[] args) {
	//newInstance()方法創(chuàng)建對象
	try {
            Class<?> clazz = Class.forName("com.yyg.Person");
            Person p2 = (Person) clazz.newInstance();
	} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
	}
    }
}

因為這一塊的內(nèi)容涉及到了反射的知識點,后面會專門講解反射,這一塊的內(nèi)容大家先有所了解即可。

3. clone()方法

第三種顯式創(chuàng)建對象的方法,就是利用實例對象的clone()方法進行對象的復制,也可以創(chuàng)建一個新對象出來。clone()方法創(chuàng)建對象時,不會調(diào)用類的構(gòu)造方法,它會創(chuàng)建一個復制的對象,這個對象和原來的對象具有不同的內(nèi)存地址,但它們的屬性值卻相同。

另外clone()方法是Java Object對象中被protected修飾的方法,可供子類調(diào)用以實現(xiàn)子類的克隆邏輯,但不能直接調(diào)用。并且我們使用該方法創(chuàng)建對象時,還要求待實例化的類必須實現(xiàn) java.lang.Cloneable接口,否則會拋出 java.lang.CloneNotSupportedException異常,比較麻煩,所以該方法并不常用。 clone()方法創(chuàng)建對象的語法格式如下:

類名 對象名 = (類名)已創(chuàng)建好的類對象名.clone();

4. readObject()方法

我們還可以使用java.io.ObjectlnputStream對象的readObject()方法來創(chuàng)建一個新對象。ObjectlnputStream是IO流中的內(nèi)容,以后會詳細講解Java中的IO流,大家對此先有一個大致的印象即可。

5. 小結(jié)

在上面給大家提到了4種顯式創(chuàng)建對象的方式,在此我們進行一個小小的總結(jié):

  • new關(guān)鍵字是最常用的創(chuàng)建對象方式;
  • 使用 new關(guān)鍵字 或 Class對象的newInstance()方法 創(chuàng)建對象時,都會調(diào)用類的構(gòu)造方法;
  • 使用 Class類的newInstance()方法 創(chuàng)建對象時,會調(diào)用類的默認構(gòu)造方法,即無參構(gòu)造方法;
  • 使用 Object類的clone()方法 創(chuàng)建對象時,不會調(diào)用此類的構(gòu)造方法,只會創(chuàng)建一個復制出的對象,該對象和原來的對象具有不同的內(nèi)存地址,但它們的屬性值相同;
  • 如果類沒有實現(xiàn)Cloneable接口卻調(diào)用它的clone()方法,會拋出 java.lang.CloneNotSupportedException異常。

三. 隱式創(chuàng)建

在Java中,除了可以顯式地創(chuàng)建對象之外,還可以隱式地創(chuàng)建對象。隱式創(chuàng)建對象主要是通過以下幾種方式:

  • 給String字符串變量賦值;
  • “+”號拼接多個字符串;
  • JVM虛擬機加載類時隱式創(chuàng)建類對象。

1. 給String字符串變量賦值

我們經(jīng)常給一個字符串變量賦值,如下所示:

String str = "Hello,壹哥";

上面的str變量,其實就是一個String對象,該對象會由JVM虛擬機隱式地創(chuàng)建出來。

2. “+”號拼接多個字符串

我們知道,“+”運算符有兩個基本作用:加法運算和字符串拼接。當進行字符串拼接時,其運算的結(jié)果是一個新的 String對象,示例如下:

String str1 = "Hello";
String str2 = "一一哥";
String str3 = str1+str2;    // str3引用一個新的String對象

通過上面的語句,JVM會隱式地創(chuàng)建出第3個String對象。

3. JVM虛擬機加載類時隱式創(chuàng)建類對象

當Java的JVM虛擬機加載一個類時,會隱式地創(chuàng)建出一個可以描述這個類的Class實例對象。類的加載是指把類的.class字節(jié)碼文件讀到內(nèi)存中,把它存放到運行時數(shù)據(jù)區(qū)的方法區(qū)中,然后會在堆區(qū)創(chuàng)建一個 java.lang.Class對象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。

4. 小結(jié)

無論我們是釆用顯式或是隱式方式創(chuàng)建對象,Java虛擬機都會在創(chuàng)建對象時包含以下步驟:

  • 給對象分配內(nèi)存;
  • 將對象的實例變量自動初始化成該變量類型的默認值;
  • 初始化對象,給實例變量賦予正確的初始值。

四. 對象的使用

1. 簡介

我們在通過一系列方式創(chuàng)建好對象之后,那么這個對象該怎么用呢?我們知道對象中有狀態(tài)和行為兩個核心要素,那怎么來調(diào)用一個對象的行為和狀態(tài)呢?Java中,一個普通的實例對象調(diào)用它的行為和狀態(tài),基本的語法格式如下:

//調(diào)用狀態(tài)

對象.屬性名;

//調(diào)用方法

對象.方法名();

接下來我們通過一個小案例給大家展示一下。

2. 使用

/** 
* @author 
*/
public class Demo02 {
    public static void main(String[] args) {
        // 對象的使用
	//先創(chuàng)建一個對象
	Person p1=new Person();
		
	//調(diào)用對象的屬性(該屬性不能是私有的,否則別的類中無法看到)--狀態(tài).
	String name = p1.name;
		
	//調(diào)用對象的方法
	p1.eat();
	p1.speak("一一哥", "男", 18);
    }
}

大家要注意,當我們在A類中調(diào)用B類對象時,B類對象的屬性或方法不能是私有的,否則在A類中會無法看到該屬性或方法。

五. 創(chuàng)建對象的內(nèi)存分析(重點)

1. 內(nèi)存簡介

Java程序在運行時,操作系統(tǒng)會給程序分配三塊主要的內(nèi)存空間:棧內(nèi)存、堆內(nèi)存、方法區(qū)。

  • 棧內(nèi)存: 棧內(nèi)存也叫做虛擬機棧,可以存放基本類型的數(shù)據(jù)和引用類型的地址,主要是局部變量。 這些 局部變量存放了編譯期可知長度的各種基本數(shù)據(jù)類型和對象引用,方法執(zhí)行完就會自動釋放。棧內(nèi)存具有先進后出、占用空間比較小、存取速度相對較快的特點。
  • 堆內(nèi)存: 堆內(nèi)存中可以存放各對象實例(所有new出來的對象都是)和數(shù)組都在堆中存放,即堆中存放的是引用類型的實際數(shù)據(jù)。 堆內(nèi)存占用的空間比較大,存取速度相對較慢。
  • 方法區(qū): 方法區(qū)主要用于存儲類信息、常量、靜態(tài)變量,靜態(tài)代碼塊、即時編譯器(JIT Compiler)編譯后的代碼數(shù)據(jù)等 , 簡單言之就是存儲類的結(jié)構(gòu)信息。類的結(jié)構(gòu)信息包括類的名稱、方法信息、字段信息等。在方法區(qū)中,有一塊空間叫做常量池(串池),用來存放字符串常量。還有一塊空間叫做靜態(tài)區(qū),用來存儲靜態(tài)變量等靜態(tài)數(shù)據(jù)。但在JDK 7之后,常量池、靜態(tài)區(qū)作為堆中的一個子部分,方法區(qū)的概念被弱化。

2. 內(nèi)存分析

/**
* @author 
*/
public class Demo02 {
    public static void main(String[] args) {
        // 對象的使用
	//先創(chuàng)建一個Person對象
	Person p1=new Person();
        p1.name="一一哥";
        p1.age=18;
        p1.sex="男";

        //創(chuàng)建p2對象
        Person p2=new Person();
    }
}

在上述代碼中,我們定義的Person類型p1變量實際上是一個引用,它會被存放在棧內(nèi)存中,而存放實際數(shù)據(jù)的Person對象則存放在堆內(nèi)存中。如下圖所示:

根據(jù)上面的內(nèi)存分析圖可知:

  • Person類中包含了name、age、sex三個屬性,它們分別是String、int、String類型。我們知道,它們的默認值分別是null、0、null。
  • 我們創(chuàng)建一個p1對象之后,p1會被存放在棧區(qū),然后p1會通過堆中Person對象的內(nèi)存地址,去找到該對象被實例化的內(nèi)容(即name、age、sex等)。
  • Java代碼中剛創(chuàng)建出來的對象屬性都是采用默認值(null、0、null),等我們通過"對象.屬性"的方式對屬性進行重新賦值后,堆內(nèi)存中存儲的才是賦值后的內(nèi)容。
  • 我們創(chuàng)建的另一個對象p2,p2依然在棧區(qū),但并沒有對p2進行初始化,所以p2的屬性在堆內(nèi)存中都是默認值。
  • 堆內(nèi)存中的每一個對象,都有一個獨立的內(nèi)存空間。

六. 結(jié)語

至此,就給大家把Java的對象介紹完畢了,現(xiàn)在你知道幾種創(chuàng)建對象的方式呢?最后再跟大家說一下,不管我們用哪種方式創(chuàng)建出來的對象,每個對象都是相互獨立的。這些不同的對象在內(nèi)存中會占有獨立的內(nèi)存地址,且每個對象都具有自己的生命周期。當一個對象的生命周期結(jié)束時,對象就變成了垃圾,這些垃圾對象會被JVM虛擬機自帶的GC垃圾回收機制來處理。

以上就是Java創(chuàng)建對象之顯示創(chuàng)建與隱式創(chuàng)建的詳細內(nèi)容,更多關(guān)于Java創(chuàng)建對象的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot如何讀取自定義外部屬性詳解

    Spring Boot如何讀取自定義外部屬性詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot如何讀取自定義外部屬性的相關(guān)資料,這個功能實現(xiàn)介紹的很詳細,需要的朋友可以參考下
    2021-05-05
  • 如何動態(tài)替換Spring容器中的Bean

    如何動態(tài)替換Spring容器中的Bean

    這篇文章主要介紹了如何動態(tài)替換Spring容器中的Bean,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Spring 整合多個配置文件的方法

    Spring 整合多個配置文件的方法

    在一些大型應用中,可能存在多個配置文件,這篇文章給大家介紹了Spring 整合多個配置文件的方法,非常不錯,具有一定的參考借鑒價值,感興趣的朋友一起看看吧
    2018-05-05
  • 自帶IDEA插件的阿里開源診斷神器Arthas線上項目BUG調(diào)試

    自帶IDEA插件的阿里開源診斷神器Arthas線上項目BUG調(diào)試

    這篇文章主要為大家介紹了自帶IDEA插件阿里開源診斷神器Arthas線上項目BUG調(diào)試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 簡單了解Java編程中線程的創(chuàng)建與守護線程

    簡單了解Java編程中線程的創(chuàng)建與守護線程

    這篇文章主要介紹了Java編程中線程的創(chuàng)建與守護線程,是Java多線程并發(fā)編程的基礎(chǔ),需要的朋友可以參考下
    2015-11-11
  • commons fileupload實現(xiàn)文件上傳的實例代碼

    commons fileupload實現(xiàn)文件上傳的實例代碼

    這篇文章主要介紹了commons fileupload實現(xiàn)文件上傳的實例代碼,包括文件上傳的原理分析等相關(guān)知識點,本文給大家介紹的非常詳細,具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-10-10
  • java 中二分法查找的應用實例

    java 中二分法查找的應用實例

    這篇文章主要介紹了java 中二分法查找的應用實例的相關(guān)資料,希望通過本文大家能掌握二分法的使用方法,需要的朋友可以參考下
    2017-09-09
  • 每日六道java新手入門面試題,通往自由的道路--多線程

    每日六道java新手入門面試題,通往自由的道路--多線程

    這篇文章主要為大家分享了最有價值的6道多線程面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對hashCode方法的設(shè)計、垃圾收集的堆和代進行剖析,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 在springboot中使用AOP進行全局日志記錄

    在springboot中使用AOP進行全局日志記錄

    這篇文章主要介紹就在springboot中使用AOP進行全局日志記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 淺談@FeignClient中name和value屬性的區(qū)別

    淺談@FeignClient中name和value屬性的區(qū)別

    這篇文章主要介紹了@FeignClient中name和value屬性的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論