JavaRush /Java Blog /Random-TW /喝咖啡休息#123。Java 建構函式 - 技術面試問答

喝咖啡休息#123。Java 建構函式 - 技術面試問答

在 Random-TW 群組發布
資料來源:哈克農

什麼是構造函數?

建構函式是一種在類別中定義的特殊方法,其名稱與類別名稱相同。Java 建構函式就像沒有傳回型別的方法。 喝咖啡休息#123。 Java 建構函式 - 技術面試問題與解答 - 1建構函數在物件的初始化中發揮最重要的作用,在本文中,我們將列出涵蓋 Java 建構函數的面試問題範例。您還將了解 Java 中建構函數的重要性,查看程式碼範例和其他重要細節,這些細節將幫助您在面試中回答有關 Java 建構函數的問題。

為什麼需要構造函數?詳細解釋

假設我們有一個名為Student的類別。我們有實例變數 name 和roll_number
class Student{
String name;
int rollNo;
}
現在,如果我們建立 1000 個對象,那麼 JVM 將使用其預設類型Name = nullrollNo = 0來初始化這些值。識別這些單獨的物件是不可能的,並且為每個物件賦值會增加程式碼量,這被認為是不好的程式設計實踐。因此,為了避免這種情況,使用了建構函數。也就是說,Java中建構函數的目的是初始化類別實例變數的值。

Java中有哪些類型的建構子?

Java 中存在三種不同類型的建構子:
  • 預設構造函數
  • 無參構造函數
  • 參數化建構函數

Java中的預設建構子是什麼?

預設建構子是 JVM 在運行時建立的建構子(如果類別中沒有定義建構子)。預設建構函數的主要工作是根據實例的預設類型初始化其值。Java 中的預設建構函式範例:
class DefaultConstructor{
int id;
String name;
}
現在對於這個類,如果我們建立一個對象,那麼在 JVM 內部將會有一個預設建構函數,它被賦予一個預設值。
DefaultConstructor df= new DefaultConstructor();
現在,如果我們列印該值,我們將得到:
列印 = df.id = 0.df.name = null。

什麼是無參構造函數?

無參構造函數是可以明確定義以初始化實例值的建構子。例如:
class NoArgConstuctor{ int a; int b;

//No Argument Constructor
NoArgConstuctor(){
a = 10;
b = 20;
}

}

什麼是參數化建構函數?

參數化建構子是接受參數來初始化實例的建構子。例如:
class ParameterizedConstuctor{
String name;
int age;
//Parameterized Constructor
ParameterizedConstuctor(String name, int age){
this.name = name;
this.age = age;
}
}

定義建構函式的規則是什麼?

要定義建構函數,必須遵循以下幾條規則:
  • 建構函數名稱必須與類別名稱相符。

  • Java 中不應該有建構函式回傳型別。

  • 建構子唯一適用的修飾符是:

    • 民眾
    • 預設
    • 受保護的
    • 私人的
  • 建構函數可以採用任意數量的參數。

  • 建構函式中不允許使用修飾符final、synchronized、static 和abstract。

  • 構造函數不支援其主體內的return語句。

  • 建構函式中的throw語句可能會出現異常。

  • 將throws 子句與建構子一起使用是可以接受的。

  • 構造函數不應產生遞歸。

什麼時候可以使用私有建構函式?

如果我們不想從外部建立某個類別的對象,我們可以使用封閉或私有建構子。透過將建構函數宣告為私有,我們只能在類別中建立物件。單例類別是使用私有建構函數的一個很好的例子。

如果我們不明確定義預設建構函數存取修飾符,它將是什麼?

預設建構函式存取修飾符始終與類別修飾符相同。如果類別是公共的,那麼建構函數也會是公共的。如果類別是私有的,那麼建構函數也會是私有的。其他存取修飾符也會發生同樣的情況。

寫出下面程式碼片段的輸出並解釋

class InterviewBit{
InterviewBit(){
System.out.println(" Welcome to InterviewBit ");
}
}
class ScalerAcademy extends InterviewBit{
ScalerAcademy(){
System.out.println(" Welcome to Scaler Academy by InterviewBit");
}
}
class Main{
public static void main(String[] args) {
ScalerAcademy sc = new ScalerAcademy();
}
}
上面的程式碼將會列印:
歡迎來到採訪比特。歡迎來到 InterviewBit 的 Scaler 學院。
我們會得到這個輸出,因為如果我們在第一行的建構函式中不包含super()this()關鍵字,JVM 會在執行時自動將其放入。JVM 這樣做是因為它繼承自另一個類,其功能也將在衍生類別中實作。因此,在給基類實例分配預設值時,JVM預設添加了super()關鍵字。

檢查程式碼並指出它是有效還是無效。解釋一下原因

class InterviewBit{
InterviewBit(){
System.out.println(" Welcome to InterviewBit ");
}
}
class ScalerAcademy extends InterviewBit{
ScalerAcademy(){
this();
System.out.println(" Welcome to Scaler Academy by InterviewBit");
}
}
class Main{
public static void main(String[] args) {
ScalerAcademy sc = new ScalerAcademy();
}
}
上面的程式碼無效,因為它與Scaler Academy建構函式內的建構子相同。這會在建構函式中建立遞歸,這是不允許的。因此,我們將收到與呼叫遞歸構造函數相關的編譯時錯誤。

我們可以在 Java 的一個類別中使用兩個建構子嗎?

是的,我們可以在一個類別中使用任意數量的建構函數,但要滿足兩個條件:
  • 建構函數參數必須不同。
  • 構造函數中不應該有遞歸。
例子。考慮同一個InterviewBit類別的兩個建構子:
InterviewBit(){
    this("Scaler"); // Calling parameterized constructor
    System.out.println(" No Argument Constructor");
}
InterviewBit(String name){
    this(); // Calling no-arg constructor
    System.out.println(" Constructor with Parameters.");
}
此程式碼無效,因為它將建立遞歸。不帶參數的建構函數會呼叫帶參數的建構函數,帶參數的建構函數會呼叫不帶參數的建構函數。

我們可以重寫 Java 中的建構函式嗎?

不,構造函數重載的概念在 Java 中不適用。

Java中的建構子可以是final的嗎?

沒有構造函數可以是最終的。這是因為Final關鍵字用於停止重寫派生類別中的方法。但在建構子中,不適用重寫的概念,因此不需要寫final關鍵字。如果我們在建構函式中寫入final關鍵字,我們將得到一個稱為必需回傳類型的編譯時錯誤,因為編譯器將其視為方法。

Java中的建構子可以是靜態的嗎?

不,Java 構造函數不能是靜態的。這是因為當我們希望成員屬於類別而不是物件時,使用 static 關鍵字。但建構函數的目的是初始化對象,因此編譯器會將其視為方法。我們將得到一個必需的返回類型錯誤。

描述一下super()、super和this()、this的差別

super()this()是建構函式呼叫。僅用於呼叫父類別或當前類別的建構子。請注意,“super”和“this”是關鍵字,用於指定其自己的類別或基底類別的實例的成員。考慮下面的程式碼:
class InterviewBit{
    String message = " Welcome to InterviewBit";
}
public class Scaler extends InterviewBit
{
    String message = " Welcome to Scaler Academy";
    public void printMethod(){
        //this will print the message variable of the current class.
        System.out.println(this.message);

        //this will print the message variable of Base class.
        System.out.println(super.message);
    }
	public static void main(String[] args) {
		Scaler sa = new Scaler();
		sa.printMethod();
	}
}
在此程式碼片段中,this.message將列印訊息“ Welcome to Scaler Academy ”,super.message將列印“ Welcome to InterviewBit ”。這就是這兩個關鍵字如何用來引用基底類別和衍生類別的成員實例。

什麼是析構函數?Java中存在析構函數嗎?

析構函數用於釋放程式所取得的記憶體。例如,如果程式在執行期間需要內存,則析構函數會釋放該內存,以便其他程式可以使用它。Java中沒有析構函數的概念,因為Java中釋放記憶體的工作是由垃圾收集器處理的。

Java 中的建構函式鍊是什麼?

當一個建構函式被另一個建構函式呼叫時,這可以稱為建構函式鏈。構造函數呼叫不必在同一個類別上進行。父類別也可以這樣做。例如,請考慮下圖。 喝咖啡休息#123。 Java 建構函式 - 技術面試問題與解答 - 2接下來我們可以看一下用這些實例變數的值來初始化物件的程式碼:
class EmployeeAddess{
    int pinCode;
    String address;
    String mobNo;
    EmployeeAddress(int pinCode, String address, String mobNo){
        this.pinCode = pinCodel
        this.address = address;
        this.mobNo = mobNo;
    }
}
class Employees extends EmployeeAddress{
    int ID;
    String name;
    String designation;
    String department;
    Employee(int ID, String name, String designation,String department,
                    int pinCode, String address, String mobNo){

        //Calling Constructor for Base class to initialize the object.
        //This can be a constructor chaining.
        super(pinCode, address, mobNo);
        this.ID = ID;
        this.name = name;
        this.designation = designation;
        this.department = department;
    }
}
public class Main{
    Employee emp = new Employee(101, "XYX", "SDE", "Cloud", 123456, "no 150, xys, xys, INDIA", "999999999");
}
在上面的程式碼中,我們建立了一個Employee類別對象,其中包含員工詳細資料及其地址。Employee地址類別由Employee類別繼承。現在,為了實例化位址的物件值,我們不會為員工的位址分配明確值。相反,我們使用Employee Address類別的建構子來執行此操作。在super(arguments)的幫助下,我們形成了一個建構函式鏈來初始化值。這就是構造函數鏈。

確定程式碼的程式輸出並解釋你的答案。

class InterviewBit{
void InterviewBit(){
System.out.println(" Java Constructor interview questions by InterviewBit");
}
int InterviewBit(int val){
System.out.println(" Java Constructor. And Value = "+val);
}
}
public class Main{
InterviewBit ib1 = new InterviewBit();
InterviewBit ib2 = new InterviewBit();
}
上面的程式碼不會印任何內容,因為InterviewBit()在這裡不是建構子。由於使用了Voidint關鍵字,它變成了一種方法。因此我們不呼叫該方法。我們不會得到任何輸出,因為要執行該方法,我們需要在物件上明確地呼叫它。

編寫一個程序,使用建構函數將物件的值複製到新物件中

class Rectangle{
    int length;
    int breadth;
    Rectangle(int length, int breadth){
        this.length = length;
        this.breadth = breadth;
    }

    //Overloaded Constructor for copying the value of old Object to new object
    Rectangle(Rectangle obj){
        this.length = obj.length;
        this.breadth = obj.breadth;
    }
}
public class Main{
    Rectangle obj1 = new Rectangle(10, 5);

    //New Object of rectangle class will be created with the value from obj1.
    Rectangle obj2 = new Rectangle(obj1);
}
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION