15.Java this 关键字/static关键字/静态初始化块/final关键字
创建对象的过程
- 分配对象空间,并将对象成员初始化为 0 或 空
- 执行属性值的显式初始化
- 执行构造方法
- 返回对象的地址给相关的变量。
this 关键字
注意点
- this 关键字用于区分局部变量和成员变量。(就近原则:优先获取最近的)
- 通过 this 可以直接指代成员变量(属性)。
- 通过 this 可以去调用类中普通的成员方法。
- 通过 this 可以去调用构造器。使用 this 关键字在一个构造器中去调用另一个重载的构造方法,可以避免相同的初始化代码。但只能在构造方法中用,且必须位于构造方法代码的第一行,否则报错。
- this 不能用于 static 方法中
- 在程序产生二义性之处,应用 this 来指明当前对象;
- 普通方法中,this 总是指向调用该方法的对象。
- 构造方法中,this 总是指向正要初始化的对象。
代码示例:上方注意点中提到的代码
public class TestThis1 {
int a,b,c;
// 定义构造方法
TestThis1(int a,int b){
this.a = a;
this.b = b;
}
// 构造方法的重载
TestThis1(int a,int b,int c){
// 调用本类中(上方)两个参数的构造方法。在一个构造器中调用另一个构造器。
this(a,b);
this.c = c;
}
// 定义普通方法
void sing(){
System.out.println("小明同学,小明同学");
}
// 定义普通方法
void eat() {
// 调用本类中的 sing() 方法
this.sing();
System.out.println("小明同学,小明同学,你妈妈给你送来了你最喜欢的旺仔牛奶。");
}
public static void main(String[] args) {
// 创建类对象,调用类方法(如果自定义了构造方法,则系统就不会自动添加无参构造方法,创建对象时就需要指定是哪个构造方法)
TestThis1 hi = new TestThis1(2,3);
hi.eat();
}
}
代码示例:this 代表 “当前对象”
public class User {
// 定义类的成员变量(类属性)
int id; // id
String name;// 账户名
String pwd; // 密码
// 定义空构造方法
public User(){
}
// 构造方法重载
public User(int id,String name){
// 测试调用方法时的 实参 到底是赋值给了谁
System.out.println(id); // 打印结果为 119
System.out.println(name); // 打印结果为 阿jun
System.out.println(pwd); // 打印结果为 null
System.out.println("正在初始化已经创建好的对象(当前对象):" + this);
// 利用 this 关键字将成员变量赋值给 User 构造方法的局部变量
this.id = id; // 不写 this,无法区分局部变量 id 和 成员变量 id
this.name = name;
}
// 定义普通方法
public void login(){
// 这里的 this.name 等同于方法里调用成员变量(属性) name
System.out.println(this.name + ",要登录!"); // 不写 this 效果一样
}
// 定义 main 方法
public static void main(String[] args) {
// 调用方法时,成员变量属性 id 和 name 都已经被分别赋值为 id=119 和 name="阿jun"
// 调用方法时定义的实参是直接赋值给了外部对应的成员变量(也叫对应类属性)
User u3 = new User(119,"阿jun");
// 此时打印的是 User 类中 u3 对象的内存地址
System.out.println("打印的是 User 类中 u3 对象的内存地址:" + u3);
u3.login();
}
}
static 关键字
简述
在类中,用 static 修饰的变量称之为静态变量,也称为类变量。
类变量的声明周期和类相同,在整个应用程序执行期间都有效。
如下特点:
- 类表里是该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
- 对于该类的所有对象来说,static 成员变量只有一份,被该类的所有对象共享。
- 一般用 “类名.属性/方法” 来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
- 在 static 方法中,不可直接访问非 static 的成员。
核心要点:
- static 修饰的成员变量和方法,从属于类。
- 普通变量和方法从属于对象。
代码示例:测试 static 关键字的用法
// 测试 static 关键字的用法
public class User2 {
int id;
String name;
String pwd;
static String company = "公众号:阿jun修炼手册"; // 定义静态变量
// 定义构造方法
public User2(int id,String name){
this.id = id;
this.name = name;
}
// 定义普通方法
public void login(){
// 普通方法中调用静态方法
printCompany();
// 普通方法中调用静态变量
System.out.println("登录名:" + company);
// 普通方法中调用普通属性
System.out.println("登录名:" + id);
}
// 定义静态方法
public static void printCompany(){
System.out.println(company);
// 下方代码会编译出错,静态方法中无法去使用非静态的方法/变量/常量,因为两者在方法区中的位置不同
// System.out.println(id);
}
public static void main(String[] args) {
// 定义类对象
User2 u = new User2(110, "120");
// 通过类名去调用方法,打印 company 静态变量
User2.printCompany();
// 静态变量重新赋值,通过类名去调用 company 静态变量
User2.company = "阿jun 都2021年了还没对象";
// 通过类名去调用方法,打印 company 静态变量
User2.printCompany();
// 对象调用静态方法
u.printCompany();
// 对象调用普通方法
u.login();
}
}
内存分析图
注意点
- 类加载完以后,类里面的相关信息(代码、静态变量/常量)会加载到 方法区 中
- 普通的方法/变量/常量 从属于类对象
- 静态的方法/变量/常量 从属于类。
- 静态方法中无法去使用非静态的方法/变量/常量。因为两者在内存的堆中的位置不同
- 在普通方法中调用静态的方法/属性,没有问题
- this 用于普通方法中,属于类,不属于对象,this 代表的是当前的对象,所以不能在静态方法里使用
- 静态方法/变量/常量 类似于汽车的图纸,非静态方法/变量/常量属类似于汽车成品。图纸中不能找到汽车,汽车中能去找图纸(有汽车,肯定就有图纸,有图纸不一定有汽车)
静态初始化块
简述
构造方法用于对象的初始化。静态初始化块,用于类的初始化操作。
在静态初始化块中不能直接访问非 static 成员。
语法格式
static {
…………
}
使用要点
- 静态块用 static 来修饰,不给定名字。
- 静态块在类初始化的时候开始执行。
- 类初始化过程中,不能去调用非静态的方法/变量,因为初始化过程中没有对象。
- 初始化类的过程,相当于是在描绘汽车图纸的过程。
- 程序在加载类的过程中,就会去将静态块的代码内容去执行。
- 类加载完成以后,才能构造对象。
代码示例:测试静态初始化块的使用
// 测试 静态初始化块
public class User3 {
int id;
String name;
String pwd;
static String company; // 定义静态成员变量
// 静态初始化块
static {
System.out.println("开始进行类的静态初始化块,company 此时的值为:" + company);
System.out.println("静态初始化块会在类加载的时候被调用执行。");
System.out.println("静态初始化块可以去调用静态的方法/变量,但不能调用非静态的方法/变量(如:id、name)");
// 调用静态成员变量并赋值
company = "公众号-阿jun修炼手册";
// 调用静态方法
printCompany();
}
// 定义静态方法
public static void printCompany(){
// 静态方法中调用静态变量
System.out.println("被赋值以后的 company 值为:" + company);
}
public static void main(String[] args) {
User3 u = null; // 这里并没有创建对象,啥也没做
}
}
注意点
静态初始化执行顺序(学继承以后再看,先了解)
- 上溯到 Object 类,先执行 Object 的静态初始化块,再向下执行子类的静态初始化块,知道我们的类静态初始化块为止。
- 构造方法执行顺序与上方所述一致。
final关键字
作用
- 修饰变量
被 final 修饰的变量不可改变。一旦赋了初值,就不能被重新赋值
final int MAX_SPEED = 120;
- 修饰方法
该方法不可被子类重写,但是可以被重载。
public final void study(){}
- 修饰符
修饰的类不能被继承。比如:Math、String 等。
final class A{}
偷偷向银河要了一把碎星✨只等你闭上眼睛撒入你的梦中。

浙公网安备 33010602011771号