java構造函數調用技巧(java構造函數的使用)

本文目錄一覽:

Java程序 構造函數並調用方法

//person類

public class Preson {

private String sex;

private String date;

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public String getDate() {

return date;

}

public void setDate(String date) {

this.date = date;

}

public Preson(String sex, String date) {

super();

this.sex = sex;

this.date = date;

}

public Preson() {

super();

// TODO Auto-generated constructor stub

}

//Student 類

public class Student extends Preson {

private String stuName;

private int stuNum;

private double stuScore;

private String stuAddress;

public String getStuName() {

return stuName;

}

public void setStuName(String stuName) {

this.stuName = stuName;

}

public int getStuNum() {

return stuNum;

}

public void setStuNum(int stuNum) {

this.stuNum = stuNum;

}

public double getStuScore() {

return stuScore;

}

public void setStuScore(double stuScore) {

this.stuScore = stuScore;

}

public String getStuAddress() {

return stuAddress;

}

public void setStuAddress(String stuAddress) {

this.stuAddress = stuAddress;

}

public Student(String sex, String date, String stuName, int stuNum,

double stuScore, String stuAddress) {

super(sex, date);

this.stuName = stuName;

this.stuNum = stuNum;

this.stuScore = stuScore;

this.stuAddress = stuAddress;

}

public Student() {

super();

// TODO Auto-generated constructor stub

}

public Student(String sex, String date) {

super(sex, date);

// TODO Auto-generated constructor stub

}

}

//test類

public static void main(String[] args) {

// TODO Auto-generated method stub

//測試1

Student stu = new Student();

stu.setSex(“男”);

stu.setDate(“1987-01-01”);

stu.setStuName(“aaa”);

stu.setStuNum(12301);

stu.setStuScore(125);

stu.setStuAddress(“上海”);

System.out.println(“出生日期:”+stu.getDate()+”性別:”+stu.getSex()

+”地址:”+stu.getStuAddress()+”姓名:”+stu.getStuName()+”學號:”

+stu.getStuNum()+”入學成績”+stu.getStuScore());

//測試二

Preson pre = new Preson();

pre.setDate(“1922-02-01”);

pre.setSex(“女”);

Student st = new Student(pre.getSex(),pre.getDate(),”bbb”,12302,135,”日本”);

System.out.print(“出生日期:”+st.getDate()+”性別:”+st.getSex()

+”地址:”+st.getStuAddress()+”姓名:”+st.getStuName()+”學號:”

+st.getStuNum()+”入學成績”+st.getStuScore());

}

java繼承中構造函數的調用順序

首先是在main函數裡面,jvm發現了程序建立了一個Sanwich的對象,於是jvm便會到Sanwich裡面找到構造函數構造一個Sanwich對象。但是jvm發現Sanwich是PortableLunch的子類,所以jvm會要先構造PortableLunch的對象。可是PortableLunch類又是Lunch的子類,所以jvm會要去構造Lunch對象。同理,Lunch又是Meal的子類,因而jvm會要構造Meal的對象。之後jvm會依照Meal、Lunch、PortableLunch、Sanwich的層次結構逐級構造出Sanwich對象,從而列印出Meal()、Lunch()、PortableLunch()、Sanwich()。但是由於Sanwich類中有Bread、Cheese、Letter三個變數,如果你沒有他們實例化的話,那麼程序就此結束;可是你給這三個變數實例化了,因此Sanwich在調用構造函數Sanwich()之後,回過頭來處理這三個實例化了的變數。所以程序又會列印出Bread()、Cheese()、Letter().

Java中構造函數是什麼?它應該具體怎麼用呢?

是構造方法,不是構造函數,後者是C++的概念

首先要注意的是Java的構造器並不是函數,所以他並不能被繼承,這在我們extends的時候寫子類的構造器時比較的常見,即使子類構造器參數和父類的完全一樣,我們也要寫super就是因為這個原因。

構造器的修飾符比較的有限,僅僅只有public private protected這三個,其他的例如任何修飾符都不能對其使用,也就是說構造器不允許被成名成抽象、同步、靜態等等訪問限制以外的形式。

因為構造器不是函數,所以它是沒有返回值的,也不允許有返回值。但是這裡要說明一下,構造器中允許存在return語句,但是return什麼都不返回,如果你指定了返回值,雖然編譯器不會報出任何錯誤,但是JVM會認為他是一個與構造器同名的函數罷了,這樣就會出現一些莫名其妙的無法找到構造器的錯誤,這裡是要加倍注意的。

在我們extends一個子類的時候經常會出現一些意想不到的問題,我在這裡說一些和構造器有關的。

首先說一下Java在構造實例時的順序(不討論裝載類的過程)

構造的粗略過程如下

1、分配對象空間,並將對象中成員初始化為0或者空,java不允許用戶操縱一個不定值的對象。

2、執行屬性值的顯式初始化(這裡有一點變化,一會解釋,但大體是這樣的)

3、執行構造器

4、將變數關聯到堆中的對象上

介紹一下準備知識,以備一會來詳細說明這個的流程

this() super()是你如果想用傳入當前構造器中的參數或者構造器中的數據調用其他構造器或者控制父類構造器時使用的,在一個構造器中你只能使用this()或者super()之中的一個,而且調用的位置只能在構造器的第一行, 在子類中如果你希望調用父類的構造器來初始化父類的部分,那就用合適的參數來調用super(),如果你用沒有參數的super()來調用父類的構造器(同時也沒有使用this()來調用其他構造器),父類預設的構造器會被調用,如果父類沒有預設的構造器,那編譯器就會報一個錯誤,注意此處,我們經常在繼承父類的時候構造器中並不寫和父類有關的內容,此時如果父類沒有預設構造器,就會出現編譯器添加的預設構造器給你添麻煩的問題了哦。例如:Class b extends a{public b(){}}就沒有任何有關父類構造器的信息,這時父類的預設構造器就會被調用。

舉個SL-275中的例子

1 public class Manager extends Employee {

2 private String department;

3

4 public Manager(String name, double salary, String dept)

{

5 super(name, salary);

6 department = dept;

7 }

8 public Manager(String n, String dept) {

9 super(name);

10 department = dept;

11 }

12 public Manager(String dept) { // 這裡就沒有super(),編譯器會自動地添加一個空參數的預設super構造器,此時如果Employee類中沒有空參數的預設構造器,那就會導致一個編譯錯誤

13 department = d;

14 }

15 }

你必須在構造器的第一行放置super或者this構造器,否則編譯器會自動地放一個空參數的super構造器的,其他的構造器也可以調用super或者this,調用成一個遞歸構造鏈,最後的結果是父類的構造器(可能有多級父類構造器)始終在子類的構造器之前執行,遞歸的調用父類構造器

在具體構造類實例的過程中,上邊過程的第二步和第三步是有一些變化的,這裡的順序是這樣的,分配了對象空間及對象成員初始化為默認值之後,構造器就遞歸的從繼承樹由根部向下調用,每個構造器的執行過程是這樣的:

1、Bind構造器的參數

2、如果顯式的調用了this,那就遞歸調用this構造器然後跳到步驟5

3、遞歸調用顯式或者隱式的父類構造器,除了Object以外,因為它沒有父類

4、執行顯式的實例變數初始化(也就是上邊的流程中的第二步,調用返回以後執行,這個步驟相當於在父構造器執行後隱含執行的,看樣子像一個特殊處理)

5、執行構造器的其它部分

這裡的步驟很重要哦!!!!!

從這個步驟中可以很明顯的發現這個實例初始化時的遞歸調用過程,估計看過這個你應該能夠理解這個遞歸構造鏈是怎麼樣回事了。

這裡還是給出SL-275中的一個例子,讓你充分理解一下這個遞歸的過程。

public class Object {

public Object() {}

}

public class Employee extends Object {

private String name;

private double salary = 15000.00;

private Date birthDate;

public Employee(String n, Date DoB) {

// implicit super();

name = n;

birthDate = DoB;

}

public Employee(String n) {

this(n, null);

}

}

public class Manager extends Employee {

private String department;

public Manager(String n, String d) {

super(n);

department = d;

}

}

在創建Manager(“Joe Smith”,”Sales”):時,步驟如下

0 basic initialization

0.1 allocate memory for the complete Manager object

0.2 initialize all instance variables to their default values (0 or null)

1 call constructor: Manager(“Joe Smith”, “Sales”)

1.1 bind constructor parameters: n=”Joe Smith”, d=”Sales”

1.2 no explicit this() call

1.3 call super(n) for Employee(String)

1.3.1 bind constructor parameters: n=”Joe Smith”

1.3.2 call this(n, null) for Employee(String, Date)

1.3.2.1 bind constructor parameters: n=”Joe Smith”, DoB=null

1.3.2.2 no explicit this() call

1.3.2.3 call super() for Object()

1.3.2.3.1 no binding necessary

1.3.2.3.2 no this() call

1.3.2.3.3 no super() call (Object is the root)

1.3.2.3.4 no explicit variable initialization for Object

1.3.2.3.5 no method body to call

1.3.2.4 initialize explicit Employee variables: salary=15000.00;注意:在父構造器返回後子類才會初始化實例變數的值。

1.3.2.5 execute body: name=”Joe Smith”; date=null;

1.3.3 – 1.3.4 steps skipped

1.3.5 execute body: no body in Employee(String)

1.4 no explicit initializers for Manager

1.5 execute body: department=”Sales”

這個流程就說明了一切,這個步驟是要注意的。一會還有些內容是要涉及到這裡的。

寫在後邊的一些在使用構造器中的注意事項。

一、構造器中一定不要創建自身的實例,否則會造成調用棧溢出錯誤。這個規則也適用於對象的實例變數,如果對象中有自身的引用,這個引用一定不能在定義中或者構造器中初始化。

class a

{

a _a = new a();

public a()

{

_a = new a();

a _b = new a();

}

}

以上三種情況都會造成棧溢出,呵呵,這樣會造成一個無窮遞歸的調用棧。

二、如果父類是一個抽象類,那通過調用父類的構造器,也可以將它初始化,並且初始化其中的數據。

三、如果你要在構造器中調用一個方法時,將該方法聲明為private。

對於這個規則是需要一些說明的,假使你的父類構造器中要調用一個非靜態方法,而這個方法不是private的又被子類所重載,這樣在實際創建子類的過程中遞歸調用到了父類的構造器時,父類構造器對這個方法的調用就會由於多態而實際上調用了子類的方法,當這個子類方法需要用到子類中實例變數的時候,就會由於變數沒有初始化而出現異常(至於為什麼子類中的實例變數沒有初始化可以參考上邊的實例初始化過程),這是Java不想看到的情況。而當父類構造器中調用的方法是一個private方法時,多態就不會出現,也就不會出現父類構造器調用子類方法的情況,這樣可以保證父類始終調用自己的方法,即使這個方法中調用了父類中的實例變數也不會出現變數未初始化的情況(變數初始化總是在當前類構造器主體執行之前進行)。

java構造函數中調用構造函數的問題

不是,因為你初始化(即new)的時候調用的是無參構造函數,所以先調用的是無參構造函數,只不過你在無參構造函數中有調用了有參構造函數(即this(1)),所以當無參構造函數還沒有執行到System.out.println(“3

Default!!”);時,有參構造函數先執行了System.out.println(“3

NotDefault!!”);所以在輸出是會出現「3

NotDefault!!」在”3

Default!!”之前的情況.

在Java中如何在主函數中調用一個類的構造函數

如果有一個類的名字叫Name:則

Name o = new Name();//調用空參的構造函數

Name o = new Name(“aa”);//調用需要傳回一個字元參數的構造函數,當然得在Name類中定義這樣一個構造函數。

構造函數:構造函數(constructor)是一種特殊的方法 。主要用來在創建對象時初始化對象, 即為對象成員變數賦初始值,總與new運算符一起使用在創建對象的語句中 。特別的一個類可以有多個構造函數 ,可根據其參數個數的不同或參數類型的不同來區分它們 即構造函數的重載。構造函數的功能主要用於在類的對象創建時定義初始化的狀態。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/237834.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:08
下一篇 2024-12-12 12:08

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字元串操作中,capitalize函數常常被用到,這個函數可以使字元串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • 使用vscode建立UML圖的實踐和技巧

    本文將重點介紹在使用vscode在軟體開發中如何建立UML圖,並且給出操作交互和技巧的指導。 一、概述 在軟體開發中,UML圖是必不可少的重要工具之一。它為軟體架構和各種設計模式的…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29

發表回復

登錄後才能評論