Java基础(十):静态变量、静态方法、代码块、main方法
一、类变量 / 静态变量(static)
(一)类变量也叫静态变量 / 静态属性,为同一个类所有对象共享,存储在堆中(在类加载时就创建了,即使没创建对象也可以使用)。
(二)定义语法:
访问修饰符 static 数据类型 变量名
例:public static int count = 0;
(三)如何访问类变量:
类名.类变量名
例:Person.name
【静态变量的访问修饰符的访问权限和范围和普通属性是一样的】
二、类方法 / 静态方法(static)
(一)定义语法:
访问修饰符 static 返回数据类型 方法名(){}
例:public static int getNum(){}
(二)如何访问类变量:
类名.类方法名【推荐】
例:Person.getNum()
【静态方法的访问修饰符的访问权限和范围和普通属性是一样的】
注意事项
- 静态方法不能使用和对象有关的关键字,例如this和super
- 静态方法只能访问静态变量或静态方法
- 普通成员方法可以访问非静态 / 静态的成员和方法
三、main方法
main方法的形式:
public static void main(Stringl args){}
- main方法时虚拟机调用
- java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public
- java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static
- 该方法接收String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数
- java执行的程序 参数1 参数2 参数3
注意事项
- 在main()方法中,我们可以直接调用main方法所在类的静态方法或静态属性;
- 不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员
四、代码块
代码化块又称为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过 { } 包围起来。
不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。
基本语法:
[修饰符]{
代码
};
说明注意:
1)修饰符可选,要写的话,也只能写static
2)代码块分为两类:使用static修饰的叫静态代码块;没有static修饰的,叫普通代码块/非静态代码块
3)逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)
4); 号可以写上,也可以省略。
5)静态代码块只能调用静态属性/方法,普通代码块可以任意
(一)static代码块
-
static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行(类什么时候被加载:看以下第二点),并且只会执行一次【重要】。如果是普通代码块,每创建一个对象,就执行。
-
类什么时候被加载【重要】
(1)创建对象实例
(2)创建子类对象实例,父类也会被加载
(3)使用类的静态成员时(静态属性,静态方法)
class AA{
static {
System.out.println("AA静态代码块被执行");
}
}
class BB extends AA{
{
System.out.println("普通代码块被执行");
}
private int n2 = getN2();
public static int n1 = getN1();
static {
System.out.println("BB静态代码块被执行");
}
public static int getN1() {
System.out.println("n1初始化");
return 100;
}
public int getN2() {
System.out.println("n2初始化");
return 200;
}
}
//情况一:
//AA m1 = new AA();
//输出:AA静态代码块被执行
//情况二:
//BB m2 = new BB();
//输出:1.AA静态代码块被执行 2.BB静态代码块被执行
//情况三:
//System.out.println("输出:" + BB.n1);
//输出:1.AA静态代码块被执行 2.n1初始化 3.AA静态代码块被执行 4.输出:1000
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
(二)普通代码块
普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。
如果只是使用类的静态成员时,普通代码块并不会执行。
使用场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的利用率(在调用构造时,先执行代码块的内容,再执行构造器的内容)
public class Hello {
public static void main(String[] args) {
Movie movie1 = new Movie("lihua", 199);
Movie movie2 = new Movie("wangming", "你好");
}
}
//以下两个构造器都使用代码块
class Movie{
private String name;
private double price;
private String directer;
public static int n1 = 10000;
{
System.out.println("电影已创建");
}
public Movie(String name, double price) {
this.name = name;
this.price = price;
}
public Movie(String name, String directer) {
this.name = name;
this.directer = directer;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
五、属性初始化、代码块、构造器的调用优先级【超级重点】
在对象创建时,属性初始化、代码块、构造器的调用优先级如下:
①父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
②子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
③父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
④父类的构造方法
⑤子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
⑥子类的构造方法
静态是在加载时就被调用,所以优先级最高;子类构造器中隐含调用super()和子类普通代码块,所以先父类再子类普通代码块
public class Hello {
public static void main(String[] args) {
AA a = new AA();
}
}
class BB{
//7.父类构造器
public BB(){
System.out.println("父类BB构造器被执行");
}
//5.父类普通属性
private int n1 = getN1();
//6.父类普通代码块
{
System.out.println("父类BB普通代码块被执行");
}
//1.父类静态代码块
static {
System.out.println("父类BB静态代码块被执行");
}
//2.父类静态属性
public static int n0 = getN0();
public static int getN0() {
System.out.println("父类静态属性n0初始化");
return 0;
}
public int getN1() {
System.out.println("父类普通属性n1初始化");
return 100;
}
}
class AA extends BB{
//10.构造器
public AA(){
//隐含 super()和调用普通代码块
System.out.println("子类AA构造器被执行");
}
//8.普通代码块
{
System.out.println("普通代码块被执行");
}
//9.普通变量初始化
private int n3 = getN3();
//3.静态变量初始化
public static int n2 = getN2();
//4.静态代码块
static {
System.out.println("子类AA静态代码块被执行");
}
public static int getN2() {
System.out.println("子类静态属性n2初始化");
return 200;
}
public int getN3() {
System.out.println("子类普通属性n3初始化");
return 300;
}
}
输出:
父类BB静态代码块被执行
父类静态属性n0初始化
子类静态属性n2初始化
子类AA静态代码块被执行
父类普通属性n1初始化
父类BB普通代码块被执行
父类BB构造器被执行
普通代码块被执行
子类普通属性n3初始化
子类AA构造器被执行
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
特别说明
本文章是个人整理的学习笔记,参考b站韩顺平老师的课程(【零基础 快速学Java】韩顺平 零基础30天学会Java)。老师讲的非常好,有兴趣的可以去看一下。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2023-08-08 第五节:EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope)
2023-08-08 EF Core事务
2023-08-08 如何改变linux服务器系统时区和时间 修改设置Linux服务器时区
2023-08-08 详解Jvm中时区设置方式,推荐 代码中TimeZone.getTimeZone("Asia/Shanghai") 而不使用TimeZone.getTimeZone("GMT+8")
2023-08-08 @Transactional(rollbackFor = Exception.class) 详解 推荐的事务注解方式 @Transactional(rollbackFor = Exception.class)
2019-08-08 转:异步提交表单插件jquery.form.min.js的使用实例,后台net同样可以接收到Excel文件进行处理
2019-08-08 jquery.form.min.js的ajaxSubmit上传Excel文件,后台返回不是标准json格式回调函数中 textstatus报错parsererror