构造方法:
1.对象都有构造方法
2.如果没有,编译器添加一个default构造方法。
抽象类也有构造方法,而且他的子类也会调它的构造方法。
调用本类或者父类的构造方法
this调用本类的构造方法,super调用父类的构造方法。(this,super要放在第一条语句,并且最多只能有一条)
所有父类的构造方法必须都得到调用 否则对象的构建就不正确
public class ConstructCallThisAndSuper {
public static void main(String[] args) {
Person p = new Graduate();
/*
* 先调用父类的构造函数 一直上述到Object类 所以此题输出结果为:
* (调用构造函数的顺序(带输出语句的那些构造函数))
In Person(String,int)
In Student(String int String)
In Student()
In Graduate()
*/
}
}
public class Person {
String name;
int age;
Person() {
}
Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("In Person(String,int)");
}
}
public class Student extends Person{
String school;
Student(){
this(null,0,null);
System.out.println("In Student()");
}
public Student(String name, int age, String school) {
// TODO Auto-generated constructor stub
super(name,age);
this.school = school;
System.out.println("In Student(String int String)");
}
}
public class Graduate extends Student{
String teacher = "";
Graduate() {
System.out.println("In Graduate()");
}
}
对象初始化:
/* 创建对象时初始化 */
Person p = new Graduate(){{age=18;name="xiaobai";}};
1.可以针对没有构造函数 但是又要赋初值的情况
2.是使用双括号的。
实例初始化与静态初始化
直接看这个代码吧
public class InitialTest {
public InitialTest(int a) {
// TODO Auto-generated constructor stub
this.a = a;
}
int a;
{ /* 实例初始化 先与构造函数执行(除了this和super..)*/
a= 5;
System.out.println("InitialTest.." + this.a);
}
static int x;
static { /*静态初始化 在第一次使用这个类的时候要执行 总是先于实例的初始化*/
x++;
System.out.println("static.." + x);
}
public static void main(String[] args) {
InitialTest initialTest = new InitialTest(4);
System.out.println(initialTest.a + " "+ InitialTest.x);
/* 输出结果:static..1
InitialTest..5
4 1(很容易看出调用顺序)
*/
}
}
构造方法的执行过程
1.调用本类或父类的构造方法,直至Object
2.按照声明顺序执行字段的初始化赋值
3.执行构造函数中各初始化语句(除了this和super)
public class JavaPConstrutor {
int a = 2000;
public JavaPConstrutor() {
this.a = 3000;
}
}
用javap对上述代码进行反汇编:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: aload_0
5: sipush 2000
8: putfield #12 // Field a:I
11: aload_0
12: sipush 3000
15: putfield #12 // Field a:I
18: return
可以看到先执行super()方法 调用Object构造函数 然后执行字段a初始化赋值2000 然后执行构造函数中的初始化语句 赋值3000.
再看一个例子:
public class Person {
String name;
int age = -1;
Person(String name, int age) {
this.name = name;
this.age = age;
sayHello(); /*虚方法 直接跳到子类执行 */
}
void sayHello() {
// TODO Auto-generated method stub
System.out.println(name+" "+age);
}
public static void main(String[] args) {
Student student = new Student("LiMing", 18 , "西南科技大学");/* 输出 LiMing 18 null*/
System.out.println(student.school); /* 西南科技大学 */
}
}
public class Student extends Person {
String school = "未定学校";//step2
public Student(String name, int age, String school) {
// TODO Auto-generated constructor stub
super(name, age); //step1
this.school = school;//step3
}
void sayHello(){
System.out.println(name+" "+age+" "+school); /*由于目前处于step1阶段 school 还没有赋值 所以输出school为NULL*/
}
}
this