构造方法/构造器
我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给 他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接指定这个 对象的年龄和姓名,该怎么做?这时就可以使用构造器。
基本语法
[修饰符] 方法名 (形参列表){
//这里的方法名就是构造器的名字
方法体;
}
1)构造器的修饰符可以默认 ,也可以是public protected private
2)构造器没有返回值
3)方法名和类名字必须一样
4)参数列表和成员方法一样的规则
5)构造器的调用由系统完成
6)如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造器(也叫默认构造方法),比如Dog (){}
, 使用javap指令反编译看看
class Dog{
//如果程序员没有自定义构造器的话,系统会自动给类生成一个默认无参的构造器
/*
默认构造器
Dog(){
}
/*
}
反编译的具体流程:
先到cmd终端编译一次这个代码
javac ConstructorDetail.java
此时编译之后 ,输入
dir
可以看到目录下面出现了一个 Dod.class通过一个反编译工具 即javap.exe
javap Dod.class
此时就可以看到了 class Dog{ Dog( ) }
关于javap
1)javap是JDK提供的一个命令行工具,javap能对给定的class文件提供的字节代码进行反编译。
也就是可以反编译成为可以看得懂的源文件
2)通过它,可以对照源代码和字节码,从而了解很多编译器内部的工作,对更深入地理解如何提高程序执行的效率等问题有极大的帮助。
3)使用格式
javap <options> <classes>
常用 : javap -c -v
7)一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下,即:Person (){}
构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。
它有几个特点:
1)方法名和类名相同 2)没有返回值 3)在创建对象时,系统会自动的调用该类的构造器完成对象的初始化。
·注意事项和使用细节
ConstructorDetail.java
1.一个类可以定义多个不同的构造器,即构造器重载 比如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名, 不需要指定年龄 2.构造器名和类名要相同 3.构造器没有返回值 4.构造器是完成对象的初始化,并不是创建对象 5.在创建对象时,系统自动的调用该类的构造方法
public class ConstructorDetail {
public static void main(String[] args) {
Person1 p1 =new Person1("King",40);
Person1 p2 =new Person1("King");
}
}
class Person1{
String name;
int age;
//第一个构造器
public Person1(String pName,int Page){
name = pName;
age = Page;
}
//第二个构造器,本质是个方法
//不指定人名,不需要指定年龄
public Person1(String pName){
//如果将构造器的名字更改为类名以外的名字,那就会是一个方法,需要返回值
name = pName;
}
//同时也可以看到两个构造器一致,这就是重载
}
//还需要注意的是,构造器不是成员方法,也就是不能调用,p1.Person1是不可行的
课堂练习题
ConstructorExercise.java
在前面定义的Person类中添加两个构造器:
第一个无参构造器:利用构造器设置所有人的age属性初始值都为18
第二个带pName和pAge两个参数的构造器:使得每次创建Person对象的同时初始化对象的age属性值和name属性值。分别使用不同的构造器,创建对象
public class ConstructorExercise {
public static void main(String[] args) {
Person2 p1 = new Person2();
System.out.println("年龄为:age"+p1.agesx+"姓名为"+p1.Oxname);
Person2 p2 = new Person2("mike",50);
System.out.println("年龄为:age"+p2.agesx+"姓名为"+p2.Oxname);
}
}
class Person2{
String Oxname;
int agesx;
public Person2() {
agesx = 18;
}
public Person2(String Oname ,int Pages){
Oxname = Oname;
agesx = Pages;
}
}
对象创建的流程分析
·看一个案例
class Person{
int age = 90;
String name;
Person(String n,int a){
//构造器
name = n;
//给属性赋值
age = a;
}}
Person p = new Person("小倩",20);
1.现在方法区加载一个Person类 — > 加载Person类信息(Person.class) ,只会加载一次
2.之后就在堆中开辟两个空间 即age name –> 在堆中分配空间(地址)
3.之后就开始初始化 — > 完成对象的初始化 (默认初始化 和 显式初始化 最后执行构造器的初始化)
4.需要注意的是 ,初始化是先进行默认初始化 ,也就是age为0 , name为null
5.之后显式初始化之后 age就为90 ,name没赋值因此还是 null
6.构造器开始执行对 对象进行初始化的操作
7.构造器将String n传给name属性 ,int a 传给age属性
8.在常量池中有一块空间即小倩 和 20 ,此时这块空间的地址就会和传参的堆空间的n(即name) ,20的空间地址传给a(即堆中的age)
9.传参之后堆空间的name为 “小倩” ,age为 20 — > 在对象堆空间的地址返回给p (p是对象名 ,也可以理解为是对象的引用)
10.此时栈中p就指向 name 和 age的堆空间 (这里的p就是Peroson p = new Person("小倩",20)
)
11.需要注意的是对象是指堆中的内容 ,而栈中的p只是对象的引用 , 或者仅仅只是一个对象名
黑色字体就是简化的步骤
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/245302.html