资料来源:哈克农
什么是构造函数?
构造函数是在类中定义的一种特殊方法,其名称与类名相同。Java 构造函数就像没有返回类型的方法。 构造函数在对象的初始化中发挥着最重要的作用,在本文中,我们将列出涵盖 Java 构造函数的面试问题示例。您还将了解 Java 中构造函数的重要性,查看代码示例和其他重要细节,这些细节将帮助您在面试中回答有关 Java 构造函数的问题。为什么需要构造函数?详细解释
假设我们有一个名为Student的类。我们有实例变量 name 和roll_number。class Student{
String name;
int rollNo;
}
现在,如果我们创建 1000 个对象,那么 JVM 将使用其默认类型Name = null和rollNo = 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(){
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 中的构造函数链是什么?
当一个构造函数被另一个构造函数调用时,这可以称为构造函数链。构造函数调用不必在同一个类上进行。父类也可以这样做。例如,请考虑下图。 接下来我们可以看一下用这些实例变量的值来初始化对象的代码: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()在这里不是构造函数。由于使用了Void和int关键字,它就变成了一种方法。因此我们不调用该方法。我们不会得到任何输出,因为要执行该方法,我们需要在对象上显式调用它。
编写一个程序,使用构造函数将对象的值复制到新对象中
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);
}
GO TO FULL VERSION