您好,登錄后才能下訂單哦!
這篇文章主要介紹Java中類與對(duì)象的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
在面向?qū)ο笾?,類和?duì)象是最基本、最重要的組成單元。類實(shí)際上是表示一個(gè)客觀世界某類群體的一些基本特征抽象。對(duì)象就是表示一個(gè)個(gè)具體的東西。所以說類是對(duì)象的抽象,對(duì)象是類的具體。
“人類”只是一個(gè)抽象的概念,它僅僅是一個(gè)概念,是不存在的實(shí)體!但是所有具備“人類”這個(gè)群體的屬性與方法的對(duì)象都叫人!這個(gè)對(duì)象“人” 是實(shí)際存在的實(shí)體!每個(gè)人都是“人”這個(gè)群體的一個(gè)對(duì)象。
在 Java 中類的成員變量定義了類的屬性。聲明成員變量的語法如下:
[public|protected|private][static][final]<type><variable_name>
各參數(shù)的含義如下。
public、protected、private
:用于表示成員變量的訪問權(quán)限。
static
:表示該成員變量為類變量,也稱為靜態(tài)變量。
final
:表示將該成員變量聲明為常量,其值無法更改。
type
:表示變量的類型。
variable_name
:表示變量名稱。
可以在聲明成員變量的同時(shí)對(duì)其進(jìn)行初始化,如果聲明成員變量時(shí)沒有對(duì)其初始化,則系統(tǒng)會(huì)使用默認(rèn)值初始化成員變量。
初始化的默認(rèn)值如下:
整數(shù)型(byte、short、int 和 long)的基本類型變量的默認(rèn)值為 0。
單精度浮點(diǎn)型(float)的基本類型變量的默認(rèn)值為 0.0f。
雙精度浮點(diǎn)型(double)的基本類型變量的默認(rèn)值為 0.0d。
字符型(char)的基本類型變量的默認(rèn)值為 “\u0000”。
布爾型的基本類型變量的默認(rèn)值為 false。
數(shù)組引用類型的變量的默認(rèn)值為 null。如果創(chuàng)建了數(shù)組變量的實(shí)例,但沒有顯式地為每個(gè)元素賦值,則數(shù)組中的元素初始化值采用數(shù)組數(shù)據(jù)類型對(duì)應(yīng)的默認(rèn)值。
聲明成員方法可以定義類的行為,行為表示一個(gè)對(duì)象能夠做的事情或者能夠從一個(gè)對(duì)象取得的信息。類的各種功能操作都是用方法來實(shí)現(xiàn)的,屬性只不過提供了相應(yīng)的數(shù)據(jù)。一個(gè)完整的方法通常包括方法名稱、方法主體、方法參數(shù)和方法返回值類型。若方法有返回值,則在方法體中用 return 語句指明要返回的值。
關(guān)于方法的參數(shù),經(jīng)常會(huì)提到形參與實(shí)參,形參是定義方法時(shí)參數(shù)列表中出現(xiàn)的參數(shù),實(shí)參是調(diào)用方法時(shí)為方法傳遞的參數(shù)。
方法的形參和實(shí)參具有以下特點(diǎn):
形參變量只有在被調(diào)用時(shí)才分配內(nèi)存單元,在調(diào)用結(jié)束時(shí),即刻釋放所分配的內(nèi)存單元。因此,形參只有在方法內(nèi)部有效,方法調(diào)用結(jié)束返回主調(diào)方法后則不能再使用該形參變量。
實(shí)參可以是常量、變量、表達(dá)式、方法等,無論實(shí)參是何種類型的量,在進(jìn)行方法調(diào)用時(shí),它們都必須具有確定的值,以便把這些值傳送給形參。因此應(yīng)預(yù)先用賦值、輸入等辦法使實(shí)參獲得確定值。
實(shí)參和形參在數(shù)量、類型和順序上應(yīng)嚴(yán)格一致,否則會(huì)發(fā)生“類型不匹配” 的錯(cuò)誤。
方法調(diào)用中發(fā)生的數(shù)據(jù)傳送是單向的,即只能把實(shí)參的值傳送紿形參,而不能把形參的值反向地傳送給實(shí)參。因此在方法調(diào)用過程中,形參的值發(fā)生改變,而實(shí)參中的值不會(huì)變化。
實(shí)參變量對(duì)形參變量的數(shù)據(jù)傳遞是“值傳遞”,即只能由實(shí)參傳遞給形參,而不能由形參傳遞給實(shí)參。程序中執(zhí)行到調(diào)用成員方法時(shí),Java 把實(shí)參值復(fù)制到一個(gè)臨時(shí)的存儲(chǔ)區(qū)(棧)中,形參的任何修改都在棧中進(jìn)行,當(dāng)退出該成員方法時(shí),Java 自動(dòng)清除棧中的內(nèi)容。
在方法體內(nèi)可以定義本方法所使用的變量,這種變量是局部變量。它的生存期與作用域是在本方法內(nèi),也就是說,局部變量只能在本方法內(nèi)有效或可見,離開本方法則這些變量將被自動(dòng)釋放。
在方法體內(nèi)定義變量時(shí),變量前不能加修飾符。局部變量在使用前必須明確賦值,否則編譯時(shí)會(huì)出錯(cuò)。另外,在一個(gè)方法內(nèi)部,可以在復(fù)合語句(把多個(gè)語句用括號(hào){}括起來組成的一個(gè)語句稱復(fù)合語句)中定義變量,這些變量只在復(fù)合語句中有效。
在具體實(shí)際開發(fā)過程中,有時(shí)方法中參數(shù)的個(gè)數(shù)是不確定的。為了解決這個(gè)問題,在 J2SE 5.0 版本中引入了可變參數(shù)的概念。
聲明可變參數(shù)的語法格式如下:
methodName({paramList},paramType…paramName)
其中,methodName 表示方法名稱;paramList 表示方法的固定參數(shù)列表;paramType 表示可變參數(shù)的類型;… 是聲明可變參數(shù)的標(biāo)識(shí);paramName 表示可變參數(shù)名稱。
注意:可變參數(shù)必須定義在參數(shù)列表的最后。
public class StudentTestMethod { // 定義輸出考試學(xué)生的人數(shù)及姓名的方法 public void print(String...names) { int count = names.length; // 獲取總個(gè)數(shù) System.out.println("本次參加考試的有"+count+"人,名單如下:"); for(int i = 0;i < names.length;i++) { System.out.println(names[i]); } } public static void main(String[] args) { // TODO Auto-generated method stub StudentTestMethod student = new StudentTestMethod(); student.print("張強(qiáng)","李成","王勇"); // 傳入3個(gè)值 student.print("馬麗","陳玲"); } }
構(gòu)造方法是類的一種特殊方法,用來初始化類的一個(gè)新的對(duì)象,在創(chuàng)建對(duì)象(new 運(yùn)算符)之后自動(dòng)調(diào)用。Java 中的每個(gè)類都有一個(gè)默認(rèn)的構(gòu)造方法,并且可以有一個(gè)以上的構(gòu)造方法。
Java 構(gòu)造方法有以下特點(diǎn):
方法名必須與類名相同
可以有 0 個(gè)、1 個(gè)或多個(gè)參數(shù)
沒有任何返回值,包括 void
默認(rèn)返回類型就是對(duì)象類型本身
只能與 new 運(yùn)算符結(jié)合使用
值得注意的是,如果為構(gòu)造方法定義了返回值類型或使用 void 聲明構(gòu)造方法沒有返回值,編譯時(shí)不會(huì)出錯(cuò),但 Java 會(huì)把這個(gè)所謂的構(gòu)造方法當(dāng)成普通方法來處理。
這時(shí)候大家可能會(huì)產(chǎn)生疑問,構(gòu)造方法不是沒有返回值嗎?為什么不能用 void 聲明呢?
簡單的說,這是 Java 的語法規(guī)定。實(shí)際上,類的構(gòu)造方法是有返回值的,當(dāng)使用 new 關(guān)鍵字來調(diào)用構(gòu)造方法時(shí),構(gòu)造方法返回該類的實(shí)例,可以把這個(gè)類的實(shí)例當(dāng)成構(gòu)造器的返回值,因此構(gòu)造器的返回值類型總是當(dāng)前類,無須定義返回值類型。但必須注意不要在構(gòu)造方法里使用 return 來返回當(dāng)前類的對(duì)象,因?yàn)闃?gòu)造方法的返回值是隱式的。
注意:構(gòu)造方法不能被 static、final、synchronized、abstract 和 native(類似于 abstract)修飾。構(gòu)造方法用于初始化一個(gè)新對(duì)象,所以用 static 修飾沒有意義。構(gòu)造方法不能被子類繼承,所以用 final 和 abstract 修飾沒有意義。多個(gè)線程不會(huì)同時(shí)創(chuàng)建內(nèi)存地址相同的同一個(gè)對(duì)象,所以用 synchronized 修飾沒有必要。
在一個(gè)類中定義多個(gè)具有不同參數(shù)的同名方法,這就是方法的重載。
如果在類中沒有定義任何一個(gè)構(gòu)造方法,則 Java 會(huì)自動(dòng)為該類生成一個(gè)默認(rèn)的構(gòu)造方法。默認(rèn)的構(gòu)造方法不包含任何參數(shù),并且方法體為空。
無參構(gòu)造方法和有參構(gòu)造方法如下:
public class MyClass { private int m; // 定義私有變量 MyClass() { // 定義無參的構(gòu)造方法 m = 0; } MyClass(int m) { // 定義有參的構(gòu)造方法 this.m = m; } }
大部分時(shí)候,普通方法訪問其他方法、成員變量時(shí)無須使用 this 前綴,但如果方法里有個(gè)局部變量和成員變量同名,但程序又需要在該方法里訪問這個(gè)被覆蓋的成員變量,則必須使用 this 前綴。
// 創(chuàng)建構(gòu)造方法,為上面的3個(gè)屬性賦初始值 public Teacher(String name,double salary,int age) { this.name = name; // 設(shè)置教師名稱 this.salary = salary; // 設(shè)置教師工資 this.age = age; // 設(shè)置教師年齡 }
this 關(guān)鍵字最大的作用就是讓類中一個(gè)方法,訪問該類里的另一個(gè)方法或?qū)嵗兞俊?/p>
public class Dog { // 定義一個(gè)jump()方法 public void jump() { System.out.println("正在執(zhí)行jump方法"); } // 定義一個(gè)run()方法,run()方法需要借助jump()方法 public void run() { // 使用this引用調(diào)用run()方法的對(duì)象 this.jump(); System.out.println("正在執(zhí)行run方法"); } }
this( )訪問構(gòu)造方法
public class Student { String name; // 無參構(gòu)造方法(沒有參數(shù)的構(gòu)造方法) public Student() { this("張三"); } // 有參構(gòu)造方法 public Student(String name) { this.name = name; } // 輸出name和age public void print() { System.out.println("姓名:" + name); } public static void main(String[] args) { Student stu = new Student(); stu.print(); } }
注意:
this( ) 不能在普通方法中使用,只能寫在構(gòu)造方法中。
在構(gòu)造方法中使用時(shí),必須是第一條語句。
在類中,使用 static 修飾符修飾的屬性(成員變量)稱為靜態(tài)變量,也可以稱為類變量,常量稱為靜態(tài)常量,方法稱為靜態(tài)方法或類方法,它們統(tǒng)稱為靜態(tài)成員,歸整個(gè)類所有。
靜態(tài)成員不依賴于類的特定實(shí)例,被類的所有實(shí)例共享,就是說 static 修飾的方法或者變量不需要依賴于對(duì)象來進(jìn)行訪問,只要這個(gè)類被加載,Java 虛擬機(jī)就可以根據(jù)類名找到它們。
調(diào)用靜態(tài)成員的語法形式如下:
類名.靜態(tài)成員
注意:
static 修飾的成員變量和方法,從屬于類。
普通變量和方法從屬于對(duì)象。
靜態(tài)方法不能調(diào)用非靜態(tài)成員,編譯會(huì)報(bào)錯(cuò)。
類的成員變量可以分為以下兩種:
靜態(tài)變量(或稱為類變量),指被 static 修飾的成員變量。
實(shí)例變量,指沒有被 static 修飾的成員變量。
靜態(tài)變量與實(shí)例變量的區(qū)別如下:
運(yùn)行時(shí),Java 虛擬機(jī)只為靜態(tài)變量分配一次內(nèi)存,在加載類的過程中完成靜態(tài)變量的內(nèi)存分配。
在類的內(nèi)部,可以在任何方法內(nèi)直接訪問靜態(tài)變量。
在其他類中,可以通過類名訪問該類中的靜態(tài)變量。
每創(chuàng)建一個(gè)實(shí)例,Java 虛擬機(jī)就會(huì)為實(shí)例變量分配一次內(nèi)存。
在類的內(nèi)部,可以在非靜態(tài)方法中直接訪問實(shí)例變量。
在本類的靜態(tài)方法或其他類中則需要通過類的實(shí)例對(duì)象進(jìn)行訪問。
靜態(tài)變量在類中的作用如下:
靜態(tài)變量可以被類的所有實(shí)例共享,因此靜態(tài)變量可以作為實(shí)例之間的共享數(shù)據(jù),增加實(shí)例之間的交互性。
如果類的所有實(shí)例都包含一個(gè)相同的常量屬性,則可以把這個(gè)屬性定義為靜態(tài)常量類型,從而節(jié)省內(nèi)存空間。例如,在類中定義一個(gè)靜態(tài)常量 PI。
public class StaticVar { public static String str1 = "Hello"; public static void main(String[] args) { String str2 = "World!"; // 直接訪問str1 String accessVar1 = str1+str2; System.out.println("第 1 次訪問靜態(tài)變量,結(jié)果為:"+accessVar1); // 通過類名訪問str1 String accessVar2 = StaticVar.str1+str2; System.out.println("第 2 次訪問靜態(tài)變量,結(jié)果為:"+accessVar2); // 通過對(duì)象svt1訪問str1 StaticVar svt1 = new StaticVar(); svt1.str1 = svt1.str1+str2; String accessVar3 = svt1.str1; System.out.println("第3次訪向靜態(tài)變量,結(jié)果為:"+accessVar3); // 通過對(duì)象svt2訪問str1 StaticVar svt2 = new StaticVar(); String accessVar4 = svt2.str1+str2; System.out.println("第 4 次訪問靜態(tài)變量,結(jié)果為:"+accessVar4); } }
運(yùn)行該程序后的結(jié)果如下所示。
第 1 次訪問靜態(tài)變量,結(jié)果為:HelloWorld!
第 2 次訪問靜態(tài)變量,結(jié)果為:HelloWorld!
第 3 次訪向靜態(tài)變量,結(jié)果為:HelloWorld!
第 4 次訪問靜態(tài)變量,結(jié)果為:HelloWorld!World!
與成員變量類似,成員方法也可以分為以下兩種:
靜態(tài)方法(或稱為類方法),指被 static 修飾的成員方法。
實(shí)例方法,指沒有被 static 修飾的成員方法。
靜態(tài)方法與實(shí)例方法的區(qū)別如下:
靜態(tài)方法不需要通過它所屬的類的任何實(shí)例就可以被調(diào)用,因此在靜態(tài)方法中不能使用 this 關(guān)鍵字,也不能直接訪問所屬類的實(shí)例變量和實(shí)例方法,但是可以直接訪問所屬類的靜態(tài)變量和靜態(tài)方法。另外,和 this 關(guān)鍵字一樣,super 關(guān)鍵字也與類的特定實(shí)例相關(guān),所以在靜態(tài)方法中也不能使用 super 關(guān)鍵字。
在實(shí)例方法中可以直接訪問所屬類的靜態(tài)變量、靜態(tài)方法、實(shí)例變量和實(shí)例方法。
public class StaticMethod { public static int count = 1; // 定義靜態(tài)變量count public int method1() { // 實(shí)例方法method1 count++; // 訪問靜態(tài)變量count并賦值 System.out.println("在靜態(tài)方法 method1()中的 count="+count); // 打印count return count; } public static int method2() { // 靜態(tài)方法method2 count += count; // 訪問靜態(tài)變量count并賦值 System.out.println("在靜態(tài)方法 method2()中的 count="+count); // 打印count return count; } public static void PrintCount() { // 靜態(tài)方法PrintCount count += 2; System.out.println("在靜態(tài)方法 PrintCount()中的 count="+count); // 打印count } public static void main(String[] args) { StaticMethod sft = new StaticMethod(); // 通過實(shí)例對(duì)象調(diào)用實(shí)例方法 System.out.println("method1() 方法返回值 intro1="+sft.method1()); // 直接調(diào)用靜態(tài)方法 System.out.println("method2() 方法返回值 intro1="+method2()); // 通過類名調(diào)用靜態(tài)方法,打印 count StaticMethod.PrintCount(); } }
運(yùn)行該程序后的結(jié)果如下所示。
在靜態(tài)方法 method1()中的 count=2
method1() 方法返回值 intro1=2
在靜態(tài)方法 method2()中的 count=4
method2() 方法返回值 intro1=4
在靜態(tài)方法 PrintCount()中的 count=6
指 Java 類中的 static{ } 代碼塊,主要用于初始化類,為類的靜態(tài)變量賦初始值,提升程序性能。
靜態(tài)代碼塊的特點(diǎn)如下:
靜態(tài)代碼塊類似于一個(gè)方法,但它不可以存在于任何方法體中。
靜態(tài)代碼塊可以置于類中的任何地方,類中可以有多個(gè)靜態(tài)初始化塊。
Java 虛擬機(jī)在加載類時(shí)執(zhí)行靜態(tài)代碼塊,所以很多時(shí)候會(huì)將一些只需要進(jìn)行一次的初始化操作都放在 static 代碼塊中進(jìn)行。
如果類中包含多個(gè)靜態(tài)代碼塊,則 Java 虛擬機(jī)將按它們?cè)陬愔谐霈F(xiàn)的順序依次執(zhí)行它們,每個(gè)靜態(tài)代碼塊只會(huì)被執(zhí)行一次。
靜態(tài)代碼塊與靜態(tài)方法一樣,不能直接訪問類的實(shí)例變量和實(shí)例方法,而需要通過類的實(shí)例對(duì)象來訪問。
public class StaticCode { public static int count = 0; { count++; System.out.println("非靜態(tài)代碼塊 count=" + count); } static { count++; System.out.println("靜態(tài)代碼塊1 count=" + count); } static { count++; System.out.println("靜態(tài)代碼塊2 count=" + count); } public static void main(String[] args) { System.out.println("*************** StaticCode1 執(zhí)行 ***************"); StaticCode sct1 = new StaticCode(); System.out.println("*************** StaticCode2 執(zhí)行 ***************"); StaticCode sct2 = new StaticCode(); } }
如上述示例,為了說明靜態(tài)代碼塊只被執(zhí)行一次,特地添加了非靜態(tài)代碼塊作為對(duì)比,并在主方法中創(chuàng)建了兩個(gè)類的實(shí)例對(duì)象。上述示例的執(zhí)行結(jié)果為:
靜態(tài)代碼塊1 count=1
靜態(tài)代碼塊2 count=2
*************** StaticCode1 執(zhí)行 ***************
非靜態(tài)代碼塊 count=3
*************** StaticCode2 執(zhí)行 ***************
非靜態(tài)代碼塊 count=4
對(duì)象是對(duì)類的實(shí)例化。對(duì)象具有狀態(tài)和行為,變量用來表明對(duì)象的狀態(tài),方法表明對(duì)象所具有的行為。Java 對(duì)象的生命周期包括創(chuàng)建、使用和清除。在 Java 語言中創(chuàng)建對(duì)象分顯式創(chuàng)建與隱含創(chuàng)建兩種情況。
對(duì)象的顯式創(chuàng)建方式有 4 種。
使用 new 關(guān)鍵字創(chuàng)建對(duì)象
這是常用的創(chuàng)建對(duì)象的方法,語法格式如下:
類名 對(duì)象名 = new 類名();
調(diào)用 java.lang.Class 或者 java.lang.reflect.Constuctor 類的 newlnstance() 實(shí)例方法
在 Java 中,可以使用 java.lang.Class 或者 java.lang.reflect.Constuctor 類的 newlnstance() 實(shí)例方法來創(chuàng)建對(duì)象,代碼格式如下:
java.lang.Class Class 類對(duì)象名稱 = java.lang.Class.forName(要實(shí)例化的類全稱);
類名 對(duì)象名 = (類名)Class類對(duì)象名稱.newInstance();
調(diào)用 java.lang.Class 類中的 forName() 方法時(shí),需要將要實(shí)例化的類的全稱(比如 com.mxl.package.Student)作為參數(shù)傳遞過去,然后再調(diào)用 java.lang.Class 類對(duì)象的 newInstance() 方法創(chuàng)建對(duì)象。
調(diào)用對(duì)象的 clone() 方法
該方法不常用,使用該方法創(chuàng)建對(duì)象時(shí),要實(shí)例化的類必須繼承 java.lang.Cloneable 接口。 調(diào)用對(duì)象的 clone() 方法創(chuàng)建對(duì)象的語法格式如下:
類名對(duì)象名 = (類名)已創(chuàng)建好的類對(duì)象名.clone();
下面創(chuàng)建一個(gè)示例演示常用的前三種對(duì)象創(chuàng)建方法。示例代碼如下:
public class Student implements Cloneable { // 實(shí)現(xiàn) Cloneable 接口 private String Name; // 學(xué)生名字 private int age; // 學(xué)生年齡 public Student(String name,int age) { // 構(gòu)造方法 this.Name = name; this.age = age; } public Student() { this.Name = "name"; this.age = 0; } public String toString() { return"學(xué)生名字:"+Name+",年齡:"+age; } public static void main(String[] args)throws Exception { System.out.println("---------使用 new 關(guān)鍵字創(chuàng)建對(duì)象---------"); // 使用new關(guān)鍵字創(chuàng)建對(duì)象 Student student1 = new Student("小劉",22); System.out.println(student1); System.out.println("-----------調(diào)用 java.lang.Class 的 newInstance() 方法創(chuàng)建對(duì)象-----------"); // 調(diào)用 java.lang.Class 的 newInstance() 方法創(chuàng)建對(duì)象 Class c1 = Class.forName("Student"); Student student2 = (Student)c1.newInstance(); System.out.println(student2); System.out.println("-------------------調(diào)用對(duì)象的 clone() 方法創(chuàng)建對(duì)象----------"); // 調(diào)用對(duì)象的 clone() 方法創(chuàng)建對(duì)象 Student student3 = (Student)student2.clone(); System.out.println(student3); } }
對(duì)上述示例的說明如下:
使用 new 關(guān)鍵字或 Class 對(duì)象的 newInstance() 方法創(chuàng)建對(duì)象時(shí),都會(huì)調(diào)用類的構(gòu)造方法。
使用 Class 類的 newInstance() 方法創(chuàng)建對(duì)象時(shí),會(huì)調(diào)用類的默認(rèn)構(gòu)造方法,即無參構(gòu)造方法。
使用 Object 類的 clone() 方法創(chuàng)建對(duì)象時(shí),不會(huì)調(diào)用類的構(gòu)造方法,它會(huì)創(chuàng)建一個(gè)復(fù)制的對(duì)象,這個(gè)對(duì)象和原來的對(duì)象具有不同的內(nèi)存地址,但它們的屬性值相同。
如果類沒有實(shí)現(xiàn) Cloneable 接口,則 clone。方法會(huì)拋出 java.lang.CloneNotSupportedException 異常,所以應(yīng)該讓類實(shí)現(xiàn) Cloneable 接口。
程序執(zhí)行結(jié)果如下:
---------使用 new 關(guān)鍵字創(chuàng)建對(duì)象---------
學(xué)生名字:小劉,年齡:22
-----------調(diào)用 java.lang.Class 的 newInstance() 方法創(chuàng)建對(duì)象-----------
學(xué)生名字:name,年齡:0
-------------------調(diào)用對(duì)象的done()方法創(chuàng)建對(duì)象----------
學(xué)生名字:name,年齡:0
調(diào)用 java.io.ObjectlnputStream 對(duì)象的 readObject()
除了顯式創(chuàng)建對(duì)象以外,在 Java 程序中還可以隱含地創(chuàng)建對(duì)象,例如下面幾種情況。
1)String strName = "strValue",其中的“strValue”就是一個(gè) String 對(duì)象,由 Java 虛擬機(jī)隱含地創(chuàng)建。
2)字符串的“+”運(yùn)算符運(yùn)算的結(jié)果為一個(gè)新的 String 對(duì)象,示例如下:
String str1 = "Hello";
String str2 = "Java";
String str3 = str1+str2; // str3引用一個(gè)新的String對(duì)象
3)當(dāng) Java 虛擬機(jī)加載一個(gè)類時(shí),會(huì)隱含地創(chuàng)建描述這個(gè)類的 Class 實(shí)例。
提示:類的加載是指把類的 .class 文件中的二進(jìn)制數(shù)據(jù)讀入內(nèi)存中,把它存放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè) java.lang.Class 對(duì)象,用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。
無論釆用哪種方式創(chuàng)建對(duì)象,Java 虛擬機(jī)在創(chuàng)建一個(gè)對(duì)象時(shí)都包含以下步驟:
給對(duì)象分配內(nèi)存。
將對(duì)象的實(shí)例變量自動(dòng)初始化為其變量類型的默認(rèn)值。
初始化對(duì)象,給實(shí)例變量賦予正確的初始值。
注意:每個(gè)對(duì)象都是相互獨(dú)立的,在內(nèi)存中占有獨(dú)立的內(nèi)存地址,并且每個(gè)對(duì)象都具有自己的生命周期,當(dāng)一個(gè)對(duì)象的生命周期結(jié)束時(shí),對(duì)象就變成了垃圾,由 Java 虛擬機(jī)自帶的垃圾回收機(jī)制處理。
每次 new 都相當(dāng)于開辟了一個(gè)新的對(duì)象,并開辟了一個(gè)新的物理內(nèi)存空間。如果一個(gè)對(duì)象只需要使用唯一的一次,就可以使用匿名對(duì)象,匿名對(duì)象還可以作為實(shí)際參數(shù)傳遞。
匿名對(duì)象就是沒有明確的給出名字的對(duì)象,是對(duì)象的一種簡寫形式。一般匿名對(duì)象只使用一次,而且匿名對(duì)象只在堆內(nèi)存中開辟空間,而不存在棧內(nèi)存的引用。
public class Person { public String name; // 姓名 public int age; // 年齡 // 定義構(gòu)造方法,為屬性初始化 public Person(String name, int age) { this.name = name; this.age = age; } // 獲取信息的方法 public void tell() { System.out.println("姓名:" + name + ",年齡:" + age); } public static void main(String[] args) { new Person("張三", 30).tell(); // 匿名對(duì)象 } }
程序運(yùn)行結(jié)果為:
姓名:張三,年齡:30
在以上程序的主方法中可以發(fā)現(xiàn),直接使用了“new Person("張三",30)”語句,這實(shí)際上就是一個(gè)匿名對(duì)象,與之前聲明的對(duì)象不同,此處沒有任何棧內(nèi)存引用它,所以此對(duì)象使用一次之后就等待被 GC(垃圾收集機(jī)制)回收。
匿名對(duì)象在實(shí)際開發(fā)中基本都是作為其他類實(shí)例化對(duì)象的參數(shù)傳遞的,在Java 應(yīng)用部分的很多地方都可以發(fā)現(xiàn)其用法,匿名對(duì)象實(shí)際上就是個(gè)堆內(nèi)存空間,對(duì)象不管是匿名的還是非匿名的,都必須在開辟堆空間之后才可以使用。
以上是“Java中類與對(duì)象的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。