前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值。如果现在要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造方法/构造器。
基本语法
[访问修饰符] 方法名 (参数列表){ 构造方法体; }
说明:
1) 构造器的修饰符可以默认
2) 构造器没有返回值(若前面写了返回值,就变成了成员方法)
3) 方法名 和 类 名字必须一样
4) 参数列表 和 成员方法一样的规则
5) 构造器的调用有系统JVM 来调用,当 我们创建新的对象,使用 new 的时候系统JVM来调用。
构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。
在创建一个类的新对象时,系统会自动的调用该类的构造方法完成对新对象的初始化。
简单案例
public class ConTest
{
public static void main(String[] args) {
//传统写法
// Person p1 = new Person();
// p1.name = "jack";
// p1.age = 20;
//构造器
Person p2 = new Person("tom", 30);
System.out.println(p2.name + " " + p2.age);
}
}
class Person
{
String name;
int age;
//构造器
public Person(String pName, int pAge) {
System.out.println("构造器被调用....");
name = pName;
age = pAge;
}
}
注意事项
-
一个类可以定义多个不同的构造方法,构造方法重载 比如:我们可以再给Person类定义一个构造方法,用该方法来创建新对象的时候,只指定人名,不需要指定年龄。
-
如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如 Person (){}。 可以在Dos中使用,javap -p Person.class 反编译,查看编译文件后Person类中的构造器。
-
一旦定义了自己的构造方法,默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非显示的定义一下,即: Person(){}; 。 建议在自己写了有参构造方法后,默认写上无参构造方法,避免出现报错。
-
主要作用是完成对新对象的初始化(构造方法完成), 并不是创建对象。在创建新对象时(JVM完成),系统自动的调用该类的构造方法。
简单案例
/**
可以在Dos中使用,javap -p Person.class 反编译,查看编译文件后Person类中的构造器。
在定义的Person类中添加两个构造器:
第一个无参构造器:利用构造器设置所有人的age属性初始值都为18
第二个带pName和pAge两个参数的构造器:使得每次创建Person对象的同时初始化对象的age属性值和name属性值。
*/
import java.util.Scanner;
public class Constructor_Class
{
public static void main(String[] args){
Person p1 = new Person();
Person p2 = new Person("小范",20);
p1.print();
p2.print();
}
}
class Person
{
int age;
String name;
//习惯在定义有参构造器时,写出无参的构造器
public Person(){
age = 18;
}
//有参构造器
public Person(String pName,int pAge){
name = pName;
age = pAge;
}
public void print(){
System.out.println("name:"+name+" , age:" + age);
}
}

对象创建流程分析(重点)
案例:
class Person{
int age=90;
String name;
Person(String n,int a){
name=n;
age=a;
}
}
Person p=new Person("小倩",20);
流程分析:
1) 加载 Person 类 (Person.class), 只会加载一次
2) 在堆中 开数据空间 , 得到一个地址
3) 数据的初始化(不断改变 堆空间中 age 与 name 的值)
(1) 默认初始化 age = 0, name = null
(2) 显式初始化 age = 90 , name = null
(3) 构造器初始化 age= 20 name = “小倩”
4) 把 堆中的地址,返回给 p
5) 使用
this关键字
java虚拟机会给每一个对象分配一个this关键字。this关键字指向对象自己。
例:小范说 我的 年龄是 20岁 , 小黄说 我的 年龄是 18岁。
在这句话中出现了两个"我的",但它们分别指向不同的对象。这就是this关键字。
使用方法简单案例
public class ThisTest {
public static void main(String[] args) {
Person p1 = new Person("小范", 20);
System.out.println("p1的地址(hashcode=)" + p1.hashCode());
p1.showInfo();
System.out.println("======================");
Person p2 = new Person("小黄", 18);
System.out.println("p1的地址(hashcode=)" + p2.hashCode());
p2.showInfo();
//哪个对象调用,this就代表哪个对象
// p1.m1();
// p2.m1();
}
}
class Person{
public String name; // null
public int age; //0
//形参,本质就是 局部变量
public Person(String name, int age){
//通过hashCode()可以基本区分对象地址,返回一个整数
this.name = name;
this.age = age;
System.out.println(this.name + " this.hashCode=" + this.hashCode());
}
public void m1() {
System.out.println();
System.out.println(this.name + " this.hashCode=" + this.hashCode());
}
public void showInfo(){
System.out.println(name + " " + age + " ");
}
}

this关键字细节
public class ThisDetail {
public static void main(String[] args) {
AA a = new AA();
a.m2();
System.out.println(a.name); // smith
AA a2 = new AA("king");
System.out.println(a2.name); // king
}
}
class AA {
int age = 10;
String name = "tom";
public AA() { //构造器1
//访问构造方法(构造器)语法:this(参数列表)
this("smith"); // this 可以调用其它构造器, 需要在构造器内
}
public AA(String name) {
//this用于区分当前类的成员和局部变量
this.name = name;
}
public void m1() {
//this关键字可以用来访问本类的属性、方法、构造器
System.out.println(this.age);
}
public void hi() {
System.out.println("hi");
}
public void m2() {
System.out.println("m2()");
//访问成员方法的语法:this.方法名(参数列表);
this.hi(); // 可以访问 本类的 hi();
}
}
细节说明
1) this关键字可以用来访问本类的属性、方法、构造器
2) this用于区分当前类的成员和局部变量
3) 访问成员方法的语法:this.方法名(参数列表);
4) 访问构造方法(构造器)语法:this(参数列表);
5) this不能在类定义的外部使用,只能在类定义的方法中使用
简单案例
/**
1) 类House , 要求写两个构造器
2) 构造器1 (address, price)
3) 构造器2 (address, price ,ares)
4) 分别使用不同的构造器,并输出 房子信息
*/
import java.util.Scanner;
public class Constructor_House
{
public static void main(String[] args){
House h1 = new House("111",100);
House h2 = new House("222",200,120);
h1.print();
h2.print();
}
}
class House
{
String address;
int price;
int ares;
public House(){}
public House(String address,int price){
this.address = address;
this.price = price;
}
public House(String address,int price,int ares){
// this.address = address;
// this.price = price;
this(address,price); //可以这样写,调用其他构造器帮助我们赋值
this.ares = ares;
}
public void print(){
System.out.println("房子地址:"+ this.address
+ " 价格:" + this.price + " 面积:" + this.ares);
}
}
