(一)this
this 可以看做一个变量,它是一个引用,存储在 Java 虚拟机堆内存的对象内部,this 这个
引用保存了当前对象的内存地址指向自身,任何一个堆内存的 java 对象都有一个 this
【注】this 不能出现在带有 static 的方法当中
原因:首先static 的方法,在调用的时候是不需要创建对象的,直接采用“类名”的方式调用,也就是说static 方法执行的过程中是不需要“当前对象”参与的,所以 static 的方法中不能使用 this,因为 this 代表的就是“当前对象“。
this 可以使用在实例方法当中,它指向当前正在执行这个动作的对象
可否省略
在实例方法中可以直接访问当前对象的实例变量,而“this.”是可以省略的。
只有当在实例方法中区分局部变量和实例变量的时候不能省略
public class Customer {
private String name;
public Customer(){
}
public Customer(String name){
this.name = name;//这里的“this.”不能省略
}
public void setName(String name){
this.name = name;//这里的“this.”不能省略
}
public String getName(){
return name; //这里的“this.”可以省略
}
public void shopping(){
//这里的“this.”可以省略
System.out.println(name + " is shopping!");
}
}
public class ThisTest {
int i = 10;
public static void main(String[] args) {
//System.out.println(i); i是实例变量
//这肯定是不行的,因为 main 方法带有 static,不能用 this
//System.out.println(this.i);
//可以自己创建一个对象
ThisTest tt = new ThisTest();
//通过引用访问
System.out.println(tt.i);
}
}
实例方法必须先创建对象,通过引用去调用,在以上的 main 方法中并没有创建对象,更没有 this。所以在 main 方法中无法直接访问实例方法。必须先创建对象。
public class ThisTest {
public static void main(String[] args) {
ThisTest tt = new ThisTest();
tt.doSome();
}
public void doSome(){
System.out.println("do some...");
}
}
this 使用在构造方法中
使用在构造方法第一行(只能出现在第一行,这是规定),通过当前构造方法调用本类当中其它的构造方法,其目的是为了代码复用。
调用语法:
this(实际参数列表)
有参数和无参数,实现代码的复用:
public class Date {
private int year;
private int month;
private int day;
//业务要求,默认创建的日期为 1970 年 1 月 1 日
public Date(){
//this.year = 1970;
//this.month = 1;
//this.day = 1;
this(1970 , 1, 1);//这句代码必须是构造器中的第一个语句
}
public Date(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
public class DateTest {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1.getYear() + "年 " + d1.getMonth() + "月 " + d1.getDay() + "日");
Date d2 = new Date(2008 , 8, 8);
System.out.println(d2.getYear() + "年 " + d2.getMonth() + "月 " + d2.getDay() + "日");
}
}
(二)static
修饰的变量叫做静态变量,修饰的方法叫做静态方法,修饰的代码块叫做静态代码块
凡是用 static 修饰的都是类相关的,不需要创建对象,直接通过“类名”即可访问,即
使使用“引用”去访问,在运行的时候也和堆内存当中的对象无关。
静态变量:
java 中的变量包括:局部变量和成员变量
- 在方法体中声明的变量为局部变量,有效范围很小,只能在方法体中访问,方法结束之后局部变量内存就释放了,在内存方面局部变量存储在栈当中。
- 在类体中定义的变量为成员变量,而成员变量又包括实例变量和静态变量,当成员变量声明时使用了 static 关键字,那么这种变量称为静态变量,没有使用 static 关键字称为实例变量。
[注]实例变量和静态变量区别: - 实例变量是对象级别的,每个对象的实例变量值可能不同,所以实例变量必须先创建对象,通过“引用”去访问,而静态变量访问时不需要创建对象,直接通过“类名”访问。
- 实例变量存储在堆内存当中,静态变量存储在方法区当中。
- 实例变量在构造方法执行过程中初始化,静态变量在类加载时初始化。
使用static定义变量
当一个类的所有对象的某个“属性值”不会随着对象的改变而变化的时候,建议将该属性定义为静态属性
public class Man {
//身份证号
int idCard;
//性别(所有男人的性别都是“男”)
//true 表示男,false 表示女
static boolean sex = true;
public Man(int idCard){
this.idCard = idCard;
}
}
public class ManTest {
public static void main(String[] args) {
Man jack = new Man(100);
System.out.println(jack.idCard + "," + (Man.sex ? "男" : "女"));
Man sun = new Man(101);
System.out.println(sun.idCard + "," + (Man.sex ? "男" : "女"));
Man cok = new Man(102);
System.out.println(cok.idCard + "," + (Man.sex ? "男" : "女"));
}
}
内存图:
【注】
静态变量和静态方法比较正式的方式是直接采用“类名”访问,但实际上使用“引用”也可以访问,并且空引用访问静态变量和静态方法并不会出现空指针异常。实际上,在开发中并不建议使用“引用”去访问静态相关的成员
静态代码块
类{
//静态代码块
static{
java 语句;
}
}
静态代码块当中的代码在 main 方法执行之前执行,这是因为静态代码块在类加载时执行,并且只执行一次。
静态代码块在类加载时执行,静态变量在类加载时初始化,它们在同一时间发生,所以必然会有顺序要求,如果在静态代码块中要访问 i 变量,那么 i 变量必须放到静态代码块之前
静态方法
在实际的开发中,“工具类”当中的方法一般定义为静态方法,因为工具类就是为了方便大家的使用,将方法定义为静态方法,比较方便调用,不需要创建对象,直接使用类名就可以访问。