JavaRush /Java 博客 /Random-ZH /喝咖啡休息#123。Java 构造函数 - 技术面试问答

喝咖啡休息#123。Java 构造函数 - 技术面试问答

已在 Random-ZH 群组中发布
资料来源:哈克农

什么是构造函数?

构造函数是在类中定义的一种特殊方法,其名称与类名相同。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