自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入剖析 Java 構(gòu)造器調(diào)用及類的初始化順序

開發(fā) 后端
Java 中的構(gòu)造函數(shù)或稱為構(gòu)造器,其實就是一段代碼,是在創(chuàng)建類對象的實例并為該對象分配內(nèi)存時調(diào)用該代碼塊。它是一種用于初始化對象的特殊方法。在聲明構(gòu)造函數(shù)時使用訪問修飾符也是允許的。

Java 中的構(gòu)造函數(shù)或稱為構(gòu)造器,其實就是一段代碼,是在創(chuàng)建類對象的實例并為該對象分配內(nèi)存時調(diào)用該代碼塊。它是一種用于初始化對象的特殊方法。在聲明構(gòu)造函數(shù)時使用訪問修飾符也是允許的。

掌握構(gòu)造函數(shù)是有效學習 Java 的重要組成部分。因此,本篇文章就來談?wù)剟?chuàng)建Java構(gòu)造器的有關(guān)規(guī)則、應(yīng)用以及初始化情況,以全面的理解和掌握 Java 構(gòu)造函數(shù)和相關(guān)情況。

1、構(gòu)造器規(guī)則

編寫Java構(gòu)造器必須遵循的規(guī)則有:

  • Java 構(gòu)造函數(shù)不得具有顯式返回類型;
  • 它不能是抽象的(abstract)、最終的(final)、靜態(tài)的(static)或同步的(synchronized);
  • 構(gòu)造函數(shù)名稱必須與屬于其類的名稱相同;
  • 構(gòu)造器調(diào)用構(gòu)造器的第一行原則。

2、構(gòu)造器類型

Java中有兩種構(gòu)造函數(shù):

1)默認構(gòu)造函數(shù)或無參數(shù)構(gòu)造函數(shù)

Java 默認構(gòu)造函數(shù)沒有參數(shù)。這就是為什么它也被稱為無參數(shù)構(gòu)造函數(shù)的原因。 Java 默認構(gòu)造函數(shù)的一般語法是:

  1. <class_name>(){ 
  2. //必要的初始化化代碼 

需要知道的是,如果 Java 類中沒有顯式定義構(gòu)造函數(shù),那么 Java 編譯器會自動為該類創(chuàng)建一個默認構(gòu)造函數(shù)。根據(jù)對象的類型,默認構(gòu)造函數(shù)為對象提供默認值或說默認初始化。

使用由 javac(java編譯器) 自動創(chuàng)建的默認構(gòu)造函數(shù)的缺點就是之后程序員無法設(shè)置或改變對象屬性的初始值。例如:

  1. package com.learning; 
  2. /** 
  3. * @author Solo Cui 
  4. */ 
  5. public class ConstructorDemo { 
  6. ConstructorDemo(){//無參構(gòu)造器 
  7. System.out.println("成功執(zhí)行構(gòu)造器,完成對象的創(chuàng)建。"); 
  8. public static void main(String[] args) { 
  9. ConstructorDemo cd = new ConstructorDemo() ; 

運行輸出結(jié)果如下:

成功執(zhí)行構(gòu)造器,完成對象的創(chuàng)建。

2)參數(shù)化構(gòu)造函數(shù)

任何帶有參數(shù)(一個或以上)的 Java 構(gòu)造函數(shù)都稱為參數(shù)化構(gòu)造函數(shù)。盡管參數(shù)化構(gòu)造函數(shù)通常用于為不同的 Java 對象提供不同的值,但它也可以為不同的 Java 對象提供相同的值,比如0或null。示例如下:

  1. package com.learning; 
  2. /** 
  3. * 參數(shù)化構(gòu)造器示例 
  4. * @author Solo Cui 
  5. */ 
  6. public class ParametersConstructor { 
  7.  
  8. int id; 
  9. String name
  10.  
  11. ParametersConstructor(String n,int i ) { 
  12. name = n; 
  13. id = i; 
  14.  
  15. void display(){ 
  16. System.out.println(""+id+" "+name); 
  17.  
  18. public static void main(String args[]) { 
  19. ParametersConstructor s1 = new ParametersConstructor("Solo",666); 
  20. ParametersConstructor s2 = new ParametersConstructor("Cui", 999); 
  21. s1.display(); 
  22. s2.display(); 

運行輸出結(jié)果如下:

  1. 666 Solo 
  2. 999 Cui 

3、構(gòu)造器調(diào)用

構(gòu)造器除了創(chuàng)建對象時的常規(guī)調(diào)用,在同一類內(nèi),構(gòu)造器也可調(diào)用其他構(gòu)造器。這里分兩種情況,即調(diào)用父類構(gòu)造器和調(diào)用當前子類構(gòu)造器。示例如下:

1)this形式調(diào)用

  1. package com.learning; 
  2.  
  3. /** 
  4. * 多個構(gòu)造器的類,this形式調(diào)用其他構(gòu)造器 
  5. * @author Administrator 
  6. */ 
  7. public class MyParent { 
  8. MyParent(){ 
  9. System.out.println("無參構(gòu)造器進行初始化處理……"); 
  10. MyParent(String hello){ 
  11. this(); 
  12. System.out.println("打個招呼:"+hello); 
  13. public static void main(String[] args) { 
  14. new MyParent("You're Great!"); 

這里一定要注意,調(diào)用同一類內(nèi)的其他構(gòu)造器的this()必須是是構(gòu)造器內(nèi)的第一行,是否有參數(shù),則根據(jù)調(diào)用的構(gòu)造器實際情況決定。

2)super形式調(diào)用

此種調(diào)用是針對類繼承關(guān)系的子類調(diào)用父情況。代碼示例如下:

  1. package com.learning; 
  2.  
  3. /** 
  4. * 繼承MyParent類,調(diào)用父類 
  5. * @author Administrator 
  6. */ 
  7. public class MyChild extends MyParent{ 
  8. String name ="default"
  9. MyChild(){ 
  10. //super():編譯器會隱式調(diào)用父類的無參構(gòu)造器 
  11. System.out.println("My Name is "+name); 
  12. MyChild(String n){ 
  13. super("大秦帝國");//顯式調(diào)用父類構(gòu)造器 
  14. name = n ; 
  15. void showName(){ 
  16. System.out.println("Name is "+name); 
  17.  
  18. public static void main(String[] args) { 
  19. MyChild child = new MyChild(); 
  20. child.showName(); 
  21. MyChild child2 = new MyChild("Solo"); 
  22. child2.showName(); 
  23.  

請注意:在子類未調(diào)用父類構(gòu)造器時,則編譯器會隱式的調(diào)用父類無參構(gòu)造器的,即super();若子類顯式調(diào)用父類的構(gòu)造器,則必須是在構(gòu)造器的第一行,super內(nèi)的參數(shù)根據(jù)需要傳入即可。還有一點需要注意,即this同類構(gòu)造器調(diào)用和super父子類調(diào)用不能同時出現(xiàn)在同一個構(gòu)造器內(nèi)。

4、構(gòu)造器重載

與 方法一樣, Java類中的構(gòu)造函數(shù)可以重載。構(gòu)造函數(shù)重載,是用相同的構(gòu)造函名但具有不同的參數(shù)列表。所有這些構(gòu)造器各自執(zhí)行不同的任務(wù)。

Java 編譯器通過列表中參數(shù)的總數(shù)及其類型來區(qū)分重載的構(gòu)造函數(shù)。以下代碼片段演示了 Java 中的構(gòu)造函數(shù)重載:

  1. package com.learning; 
  2.  
  3. /** 
  4. * 構(gòu)造器重載示例 
  5. * @author Solo Cui 
  6. */ 
  7. public class OverloadConstructor { 
  8.  
  9. int id; 
  10. String name
  11. int age; 
  12.  
  13. OverloadConstructor(int i, String n) { 
  14. id = i; 
  15. name = n; 
  16.  
  17. OverloadConstructor(int i, String n, int a) { 
  18. id = i; 
  19. name = n; 
  20. age = a; 
  21.  
  22. void display(){ 
  23. System.out.println("id="+id+";name="+name+";age="+age); 
  24.  
  25. public static void main(String args[]) { 
  26. OverloadConstructor s1 = new OverloadConstructor(333, "Solo"); 
  27. OverloadConstructor s2 = new OverloadConstructor(666, "Cui", 25); 
  28. s1.display(); 
  29. s2.display(); 

運行輸出結(jié)果如下:

  1. id=333;name=Solo;age=0 
  2. id=666;name=Cui;age=25 

5、構(gòu)造器與方法

簡單來講,Java 方法是一段具有特定名稱的代碼。在可訪問的范圍內(nèi),只需使用方法名稱即可在程序中的任何時間點調(diào)用它。你也可以理解為對數(shù)據(jù)進行操作,然后返回值(某特定在或void)的子程序。

Java 構(gòu)造函數(shù)是一種特殊類型的方法。兩者在許多方面相似,但并不完全相同。以下是 Java 構(gòu)造函數(shù)和 Java 方法之間一些最重要的區(qū)別:

  • 調(diào)用——子類通過super()隱式調(diào)用父類構(gòu)造函數(shù),而方法必須顯式調(diào)用;同類內(nèi)有多個構(gòu)造器時,某個構(gòu)造器調(diào)用另一個構(gòu)造器時,使用this()形式,this后括號有無參數(shù)根據(jù)調(diào)用的構(gòu)造器參數(shù)決定;而方法調(diào)用則是通過this+點(.)+方法名;
  • 編譯器——Java編譯器從不提供 Java 默認方法。但是,如果 Java 類中未定義構(gòu)造函數(shù),則 Java 編譯器會提供默認構(gòu)造函數(shù);
  • 命名約定——Java構(gòu)造函數(shù)的名稱必須與類的名稱相同。但是方法的名稱可能與包含它的類的名稱相同,也可能不同
  • 調(diào)用次數(shù)——Java 構(gòu)造函數(shù)只在對象創(chuàng)建期間被調(diào)用一次。而Java 方法可以根據(jù)需要多次調(diào)用;
  • 返回類型——Java 方法必須具有返回類型,但對于構(gòu)​造函數(shù)則不需要返回類型;
  • 用法——方法用于公開 Java 對象的行為,而構(gòu)造函數(shù)用于初始化相同對象的狀態(tài)。

6、復(fù)制構(gòu)造函數(shù)

盡管 Java 中沒有提供復(fù)制構(gòu)造函數(shù),但可以將值從一個 Java 對象復(fù)制到另一個對象,就像在 C++ 中使用復(fù)制構(gòu)造函數(shù)一樣。

除了使用構(gòu)造函數(shù)將值從一個對象復(fù)制到另一個對象外,還可以通過以下方式完成:

將一個對象的值分配給另一個對象;

或者

通過使用 Object 類的 clone() 方法。

以下程序演示了使用 Java 構(gòu)造函數(shù)將值從一個 Java 對象復(fù)制到另一個對象:

  1. package com.learning; 
  2.  
  3. /** 
  4. * 復(fù)制當前類的對象 
  5. * @author Solo Cui 
  6. */ 
  7. public class SimpleCopy { 
  8.  
  9. int id; 
  10. String name
  11.  
  12. SimpleCopy(int i, String n) { 
  13. id = i; 
  14. name = n; 
  15.  
  16. SimpleCopy(SimpleCopy s) { 
  17. id = s.id; 
  18. name = s.name
  19.  
  20. void show() { 
  21. System.out.println("id=" + id + ";name=" + name); 
  22.  
  23. public static void main(String[] args) { 
  24. SimpleCopy s1 = new SimpleCopy(138, "Solo"); 
  25. SimpleCopy s2 = new SimpleCopy(s1); 
  26. s1.show(); 
  27. s2.show(); 

7、類的初始化

在Java中類初始化可以分為兩類,即靜態(tài)初始化和非靜態(tài)初始化。當創(chuàng)建java對象時,程序總是依次調(diào)用每個父類的非靜態(tài)初始化塊、父類構(gòu)造器(總是從Object開始——Java中的始祖類)執(zhí)行初始化,最后再調(diào)用當前(子)類的非靜態(tài)初始化塊、構(gòu)造器執(zhí)行初始化。通過示例演示如下,下面我們來開看其初始化的順序:

1)父類XParent:

  1. package com.learning; 
  2.  
  3. /** 
  4. * 類初始化:父類 
  5. * @author Administrator 
  6. */ 
  7. public class XParent { 
  8. static { 
  9. System.out.println("XParent:父類【靜態(tài)】初始化塊"); 
  10. System.out.println("XParent:父類【非靜態(tài)】初始化塊"); 
  11. public XParent() { 
  12. System.out.println("XParent:父類無參構(gòu)造器"); 
  13. public XParent(String name) { 
  14. System.out.println("XParent:父類含參構(gòu)造器:name=" + name); 

2)子類XChild:

  1. package com.learning; 
  2.  
  3. /** 
  4. * 子類XChild初始化 
  5. * @author Solo cui 
  6. */ 
  7. public class XChild extends XParent { 
  8. static { 
  9. System.out.println("XChild:子類靜態(tài)初始化塊"); 
  10. System.out.println("XChild:子類非靜態(tài)初始化塊"); 
  11. public XChild() { 
  12. this("Solo"); 
  13. System.out.println("XChild:子類無參構(gòu)造器"); 
  14. public XChild(String name) { 
  15. super(name); 
  16. System.out.println("XChild:子類含參構(gòu)造器: name=" + name); 
  17. public static void main(String[] args) { 
  18. XChild c1 = new XChild("Tomy"); 
  19. XChild c2 = new XChild(); 

運行子類輸出結(jié)果為:

  1. XParent:父類【靜態(tài)】初始化塊 
  2. XChild:子類靜態(tài)初始化塊 
  3. XParent:父類【非靜態(tài)】初始化塊 
  4. XParent:父類含參構(gòu)造器:name=Tomy 
  5. XChild:子類非靜態(tài)初始化塊 
  6. XChild:子類含參構(gòu)造器: name=Tomy 
  7. XParent:父類【非靜態(tài)】初始化塊 
  8. XParent:父類含參構(gòu)造器:name=Solo 
  9. XChild:子類非靜態(tài)初始化塊 
  10. XChild:子類含參構(gòu)造器: name=Solo 
  11. XChild:子類無參構(gòu)造器 

所以,無論新實例化多少個對象,該類的所有父類以及自身的靜態(tài)初始化塊只執(zhí)行一次,而且是最先執(zhí)行的初始化,稱作類的初始化。之后的初始化會依次執(zhí)行父類的非靜態(tài)初始化塊、父類的構(gòu)造器和子類的非靜態(tài)初始化塊、子類的構(gòu)造器來完成初始化稱為對象初始化;在子類的構(gòu)造器中可以通過super來顯式調(diào)用父類的構(gòu)造器,可以通過this來調(diào)用該類重載的其他構(gòu)造器,而具體調(diào)用哪個構(gòu)造器決定于調(diào)用時的參數(shù)類型。

8、關(guān)于構(gòu)造器的FAQs

以下是一些關(guān)于 Java 構(gòu)造函數(shù)的最常見問題。

問:構(gòu)造函數(shù)是否有返回值?

答:雖然不能在 Java 構(gòu)造函數(shù)中使用返回類型,但它確實返回一個值。 Java 構(gòu)造函數(shù)返回當前類實例的引用。

問:Java 中的構(gòu)造函數(shù)鏈是什么?

答:構(gòu)造函數(shù)鏈接是在 Java 編程語言中從其他構(gòu)造函數(shù)調(diào)用構(gòu)造函數(shù)的技術(shù)。 this() 方法用于調(diào)用同一個類構(gòu)造函數(shù),而 super() 方法用于調(diào)用超類構(gòu)造函數(shù)。

問:說說在構(gòu)造器調(diào)用構(gòu)造器時,this和super的區(qū)別

答:super和this的調(diào)用只能在構(gòu)造器中,而且都必須作為構(gòu)造器中的第一行,因此super和this不會同時出現(xiàn)在同一個構(gòu)造器中。

問:在Java中可以從超類構(gòu)造函數(shù)中調(diào)用子類構(gòu)造函數(shù)嗎?

答:不行。

問:Java 有析構(gòu)函數(shù)嗎?

答:Java 沒有析構(gòu)函數(shù),因為它是垃圾自回收語言。在 Java 中無法預(yù)測對象何時會被銷毀。

問:Java 構(gòu)造函數(shù)可以執(zhí)行除初始化之外的哪些任務(wù)?

答:Java 構(gòu)造函數(shù)可以執(zhí)行任何可以使用方法執(zhí)行的操作。使用 Java 構(gòu)造函數(shù)執(zhí)行的一些最流行的任務(wù)是:

調(diào)用方法;

對象創(chuàng)建;

開始一個線程等。

問:Java 中何時需要構(gòu)造函數(shù)重載?

A:構(gòu)造函數(shù)重載在 Java 中通常用于需要以多種不同方式初始化 Java 對象的情況。

問:如果為 Java 構(gòu)造函數(shù)添加返回類型會發(fā)生什么?

答:具有返回類型的 Java 構(gòu)造函數(shù)將被視為典型的 Java 方法。

最后

 

這就是 Java 構(gòu)造函數(shù)的全部內(nèi)容。掌握好如何有效地使用構(gòu)造函數(shù)是Java編程的必備核心技能之一。根據(jù)具體學習情況多加練習和酌情使用吧。

 

責任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2012-02-28 10:04:09

Java

2013-03-04 11:10:03

JavaJVM

2010-07-28 10:22:33

FlexApplica

2012-05-23 12:46:53

JavaJava類

2012-02-27 14:09:00

Java

2011-03-23 15:02:55

ListenerFilterServlet

2009-07-03 16:21:33

Java的聲明和初始化Java

2011-06-17 15:29:44

C#對象初始化器集合初始化器

2024-03-12 07:44:53

JVM雙親委托機制類加載器

2011-07-22 17:46:43

java

2010-02-05 17:16:05

C++構(gòu)造函數(shù)

2024-03-08 08:26:25

類的加載Class文件Java

2012-03-13 13:38:42

Java

2012-04-09 13:43:12

Java

2023-12-04 10:57:52

函數(shù)C++

2012-05-16 13:45:24

Java構(gòu)造器

2019-11-04 13:50:36

Java數(shù)組編程語言

2012-12-28 14:53:34

Android開發(fā)初始化窗體事件

2011-03-17 09:58:43

Java虛擬機JVM

2009-08-27 10:31:39

C#對象初始化器
點贊
收藏

51CTO技術(shù)棧公眾號