一、什么是构造器
构造器(Constructor)是Java类的一种特殊方法,用于初始化对象的状态。构造器在创建对象时被调用,可以对对象的成员变量进行初始化。
我之前的文章《Java——类和对象-CSDN博客》中也提到了构造器。
二、构造器详细介绍
1、引入
我们之前在实例化一个类时,对创建的对象的属性初始化都是依靠一个个访问对象的属性然后一个个赋值的,这样实在太麻烦。
public class Test {public static void main(String[] args) {Person person = new Person();person.name = "张三";person.age = 19;}
}class Person {Sring name;int age;//...
}
这时,我们就可以使用构造器,构造器实际上是在创建对象时自动被调用的。
public class Test {public static void main(String[] args) {Person person = new Person("张三", 19);}
}class Person {String name;int age;//构造器public Person(String name, int age) {this.name = name;this.age = age;}
}
这样我们就能再创建对象时就直接将对象的属性初始化好了。
2、构造器介绍
1)基本语法
构造器的基本语法是:
[修饰符] 类名(参数列表) {/...
}
2)特点
- 名称与类名相同:构造器的名称必须与类名完全一致。
- 没有返回类型:构造器没有返回类型(连 void 都不能写)。
- 自动调用:构造器在使用
new
关键字创建对象时自动调用。 - 隐式构造器:如果类中没有定义任何构造器,Java编译器会自动提供一个无参的默认构造器。但是一旦用户自定义了自己的构造器,这个默认构造器就会被覆盖,就不会存在了。这个构造器就长这样:
类名() {}
- 访问修饰符:构造器的修饰符可以是public,private,protected,默认(什么都不写)。
3、构造器重载
构造器像一般方法一样,也可以重载。
public class Test {public static void main(String[] args) {Person person1 = new Person();//使用无参的构造器初始化Person person2 = new Person("张三");//使用一个名字参数的构造器初始化Person person3 = new Person("李四", 19);//使用两个参数的构造器初始化}
}class Person {String name;int age;//无参构造器public Person() {this.name = "无名";this.age = 18;}//一个名字参数的构造器public Person(String name) {this.name = name;this.age = 18;}//两个参数的构造器public Person(String name, int age) {this.name = name;this.age = age;}
}
重载的规则与一般方法的规则也是一致的。
4、构造器使用示例
public class Test {public static void main(String[] args) {Cat cat = new Cat("小喵", 3);}
}class Cat {String name;int age;//构造器public Cat(String name, int age) {this.name = name;this.age = age;}
}
使用构造器初始化 cat 对象的两个属性。
5、补充细节
1)构造器只完成对对象的初始化
构造器只完成对象的初始化,不会创建对象。
2)查看默认的构造器
上面我们说到,如果用户没有显示自定义构造器,Java编译器会自动提供一个无参的默认构造器。我们可以使用 javap 反编译查看这个构造器:
我们以下列代码为例,这里定义一个类,里面没有任何内容:
class Cat {}
然后我们使用 javac 指令进行编译,
然后使用 javap 反编译字节码文件,得到的内容如下:
我们可以看到这里是对应的一个方法的声明。
三、创建对象的同时使用构造器的具体图解
下面我们对创建对象的同时使用构造器初始化对象的属性的具体机制进行详细介绍,以以下代码为例:
public class Test {public static void main(String[] args) {Person person3 = new Person("李四", 19);//使用两个参数的构造器初始化}
}class Person {String name;int age;//构造器public Person(String name, int age) {this.name = name;this.age = age;}
}
当执行主方法中的第一句时,会加载 Person 类,然后再堆区创建 person3 这个对象,然后这个对象的属性被默认初始化为类型默认值:
然后调用构造方法将这个 person3 对象初始化。
如果在类中对某个属性有过显式初始化,例如下面:
public class Test {public static void main(String[] args) {Person person3 = new Person("李四", 19);//使用两个参数的构造器初始化}
}class Person {String name;int age = 18;//构造器public Person(String name, int age) {this.name = name;this.age = age;}
}
这里对于 age 属性就有显式初始化,接下来的初始化顺序是:
四、this 介绍
1、this 简要介绍
this
是一个指向当前对象的引用。在实例方法或构造方法中使用 this
时,它指向调用该方法或构造方法的对象实例。
2、隐式使用 this
在实例方法中,即使不显式使用 this
,JVM 也会在幕后使用 this
来引用当前对象。例如,访问实例变量 num
实际上是 this.num
。就像下面的代码:
class Person {String name;int age;public void speak() {System.out.println(name + "说:...");//这里的name就是this.name}
}
3、this 的实际内部工作机制
当实例方法被调用时,JVM 会传递一个隐藏参数给该方法,这个隐藏参数就是对调用该方法的对象的引用,也就是 this
。
五、this 使用
1、用于区分实例变量和局部变量
在方法或构造器中,如果局部变量和实例变量同名,那么局部变量会隐藏实例变量。此时可以使用 this
关键字来引用实例变量。
public class MyClass {private int num;public MyClass(int num) {this.num = num; // this.num 指的是实例变量,而 num 是构造器的参数}public void setNum(int num) {this.num = num; // this.num 指的是实例变量,而 num 是方法参数}public int getNum() {//return num; //就相当于return this.num; 这里会隐式使用thisreturn this.num; // this.num 指的是实例变量}
}
2、访问对象的属性
public class Test {public static void main(String[] args) {Person person = new Person("张三", 19);person.info();//显示信息}
}class Person {String name;int age;//构造器public Person(String name, int age) {this.name = name;this.age = age;}public void info() {System.out.println("名字:" + this.name + "\n年龄:" + this.age);}
}
运行结果:
这里的通过 this 访问到对象的 name 和 age 属性。
3、调用当前对象的方法
可以使用 this
关键字来调用当前对象的方法,尤其是在需要明确是当前实例的方法时。
class Person {String name;int age;//说话public void speak(String words) {System.out.println(this.name + "说:“" + words + "”");}//打招呼public void greet() {this.speak("你好!");//调用该对象的说话方法}
}
4、调用当前对象的构造器
在构造器内部,可以使用 this()
调用当前类的其他构造器。这个语法只能在构造器中使用。
class Person {String name;int age;//一个名字参数构造器public Person(String name) {this.name = name;}//两个参数的构造器public Person(String name, int age) {this(name);this.age = age;}
}
如果我们要使用 this() 语句在一个构造器中调用其他构造器,那么 this() 这条语句必须是这个构造器的第一条语句,就像上面这样。
也就是说对 this() 的调用必须是构造器的第一条语句。