在上一章我们简单的讲述了类和对象的基本概念,以及如何实例化,接下来承接上文先讲述类和对象中非常关键的一个概念this!!!
1.this引用
1.1为什么要有this
我们先来看一个学生的栗子:
public static Student {
public String name;
public int age;
public String gender;
public void setStudent(String name,int age,String gender){
name = name;
age = age;
gender = gender;
}
public void main(String args[]){
Student student = new Student();
student.setStudent("zhangsan",19,"男");
}
}
这个代码乍眼一看没什么问题,但是我就要提个问题了。上述代码中在设置成员变量的时候,函数体中到底是谁给谁在赋值呢?是参数给成员变量?成员变量给成员变量?参数给参数?可能问到这里我们自己已经有点搞不清楚了,就更不用说编译器了。
为了避免这种混淆,在java中我们就引用了this这个关键字。
1.2this是什么
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过this引用去访问。也就是说谁调用成员方法this就指向谁。
编译器把上述带码编译后就会转换成如下代码
public static Student {
public String name;
public int age;
public String gender;
public void setStudent(String name,int age,String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void main(String args[]){
Student student = new Student();
student.setStudent("zhangsan",19,"男");
}
}
当我们把代码写成上面这样,此时this所指向的就是student这个对象,这是setStudent方法内部的代码就可以近似的看成student.name = name......这样我们就很容易区分到底是谁给谁在赋值。
1.3this引用的特性
1.this的类型,对应类类型的引用,即哪个对象调用就是那个对象的应用类型。
2.this只能在成员方法中使用。
3.在成员方法中this只能引用当前对象,不能引用别的对象。
4.this是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法的对象的引用传递给该成员方法,this负责来接受
2.对象的构造和初始化
1.如何初始化对象
通过之前的学习我们知道,在Java中使用局部变量之前必须要初始化,否则就会报错
而我们的对象初始化和局部变量有些不同,对象是通过构造方法来进行初始化的。
构造方法就是在我们类中定义的一个方法,和普通方法不一样的是它没有返回值,名字与类名相同,在编译时被编译器自动调用。在生命周期只能被调用一次,也支持方法的重载。当我们不写时编译器会默认生成一个没有参数的构造方法
public static Student {
public String name;
public int age;
public String gender;
public Student(){
}
public Student(String name,int age,String gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void main(String args[]){
Student student1 = new Student();
Student student2 = new Student("张三",19,"男");
}
}
上述代码中我们写了两个构造方法,构造方法之间形成的重载,student1执行无参的构造方,student2调用的是有三个参数的构造方法。
2.默认初始化
在上面的代码中,大家可能会心存一个疑虑,明明student1调用的是无参的构造方法,也没有别的部分给它赋值,可代码为什么不会报错呢?
说的没错,要搞清这一点就要弄明白new关键字在背后做的一些工作了,在程序层面只是简单的一段语句,可放到jvm层面就要做许多事情了。简单来说分为下面几个步骤。
1.检测对象对应的类是否加载了,如果没有则加载。
2.为对象分配内存空间。
3.处理多并发线程安全问题
比如:多线程同时申请对象,jvm要保证分配的空间不冲突。
4.初始化所分配的空间。
5.设置对象头信息。
6.调用构造方法给对象各个成员赋值。