接上篇Java-static关键字(上),今儿继续写完,这篇文章主要内容如下:
- Java static静态代码块
- Java static静态方法
Java static静态代码块
静态代码块的语法格式是这样的:
类{
//静态代码块
static{
java语句;
}
}
静态代码块在类加载时执行,并且只执行一次。开发中使用不多,但离了它有的时候还真是没法写代码。
静态代码块实际上是java语言为程序员准备的一个特殊的时刻,这个时刻就是类加载时刻,如果你想在类加载的时候执行一段代码,那么这段代码就有的放矢了。
例如我们要在类加载的时候解析某个文件,并且要求该文件只解析一次,那么此时就可以把解析该文件的代码写到静态代码块当中了。
我们来测试一下静态代码块:
public class StaticTest01 {
//静态代码块
static{
System.out.println(2);
}
//静态代码块
static{
System.out.println(1);
}
//main方法
public static void main(String[] args) {
System.out.println("main execute!");
}
//静态代码块
static{
System.out.println(0);
}
}
运行结果如下图所示:
图1:静态代码块运行结果
通过以上的测试可以得知一个类当中可以编写多个静态代码块(尽管大部分情况下只编写一个),并且静态代码块遵循自上而下的顺序依次执行,所以有的时候放在类体当中的代码是有执行顺序的(大部分情况下类体当中的代码没有顺序要求,方法体当中的代码是有顺序要求的,方法体当中的代码必须遵守自上而下的顺序依次逐行执行),另外静态代码块当中的代码在main方法执行之前执行,这是因为静态代码块在类加载时执行,并且只执行一次。
再来看一下以下代码:
public class StaticTest02 {
int i = 100;
static{
System.out.println(i);
}
}
编译结果如下图所示:
图2:静态代码块中访问实例变量编译报错
为什么编译报错呢?
那是因为i变量是实例变量,实例变量必须先创建对象才能访问,静态代码块在类加载时执行,这个时候对象还没有创建呢,所以i变量在这里是不能这样访问的。可以考虑在i变量前添加static,这样i变量就变成静态变量了,静态变量访问时不需要创建对象,直接通过“类”即可访问,例如以下代码:
public class StaticTest02 {
static int i = 100;
static{
System.out.println("静态变量i = " + i);
}
public static void main(String[] args) {
}
}
运行结果如下图所示:
图3:静态代码块中访问静态变量
代码修改为这样呢?
public class StaticTest02 {
static{
System.out.println("静态变量i = " + i);
}
static int i = 100;
}
编译报错了,请看下图:
图4:编译报错信息
通过测试,可以看到有的时候类体当中的代码也是有顺序要求的(类体当中定义两个独立的方法,这两个方法是没有先后顺序要求的),静态代码块在类加载时执行,静态变量在类加载时初始化,它们在同一时间发生,所以必然会有顺序要求,如果在静态代码块中要访问i变量,那么i变量必须放到静态代码块之前。
Java static静态方法
方法在什么情况下会声明为静态的呢?方法实际上描述的是行为动作,我认为当某个动作在触发的时候需要对象的参与,这个方法应该定义为实例方法,例如:每个玩篮球的人都会打篮球,但是你打篮球和科比打篮球最终的效果是不一样的,显然打篮球这个动作存在对象差异化,该方法应该定义为实例方法。
再如:每个高中生都有考试的行为,但是你考试和学霸考试最终的结果是不一样的,一个上了“家里蹲大学”,一个上了“清华大学”,显然这个动作也是需要对象参与才能完成的,所以考试这个方法应该定义为实例方法。
以上描述是从设计思想角度出发来进行选择,其实也可以从代码的角度来进行判断,当方法体中需要直接访问当前对象的实例变量或者实例方法的时候,该方法必须定义为实例方法,因为只有实例方法中才有this,静态方法中不存在this。
请看代码:
public class Customer {
String name;
public Customer(String name){
this.name = name;
}
public void shopping(){
//直接访问当前对象的name
System.out.println(name + "正在选购商品!");
//继续让当前对象去支付
pay();
}
public void pay(){
System.out.println(name + "正在支付!");
}
}
public class CustomerTest {
public static void main(String[] args) {
Customer jack = new Customer("jack");
jack.shopping();
Customer rose = new Customer("rose");
rose.shopping();
}
}
运行结果如下图所示:
图5:运行结果
在以上的代码中,不同的客户购物,最终的效果都不同,另外在shopping()
方法中访问了当前对象的实例变量name
,以及调用了实例方法pay()
,所以shopping()
方法不能定义为静态方法,必须声明为实例方法。
另外,在实际的开发中,“工具类”当中的方法一般定义为静态方法,因为工具类就是为了方便大家的使用,将方法定义为静态方法,比较方便调用,不需要创建对象,直接使用类名就可以访问。
请看以下工具类,为了简化“System.out.println();
”代码而编写的工具类:
public class U {
public static void p(int data){
System.out.println(data);
}
public static void p(long data){
System.out.println(data);
}
public static void p(float data){
System.out.println(data);
}
public static void p(double data){
System.out.println(data);
}
public static void p(boolean data){
System.out.println(data);
}
public static void p(char data){
System.out.println(data);
}
public static void p(String data){
System.out.println(data);
}
}
运行结果如下图所示:
图6:测试工具类
最后
推荐给大家个比较详细的Java零基础教程,下面这个是我看过的觉得挺不错的,值得观看收藏。
分享给大家,点这里
https://www.bilibili.com/video/BV1Rx411876f
看完如果对你有帮助,感谢点赞支持~