Java零基础_学Java必备的学习笔记(十五)Java-static关键字(下)

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战java

接上篇Java-static关键字(上),今儿继续写完,这篇文章主要内容以下:程序员

  • Java static静态代码块
  • Java static静态方法

Java static静态代码块

静态代码块的语法格式是这样的:markdown

类{
//静态代码块
static{
java语句;
}
}
复制代码

静态代码块在类加载时执行,而且只执行一次。开发中使用很少,但离了它有的时候还真是无法写代码。工具

静态代码块其实是java语言为程序员准备的一个特殊的时刻,这个时刻就是类加载时刻,若是你想在类加载的时候执行一段代码,那么这段代码就有的放矢了。post

例如咱们要在类加载的时候解析某个文件,而且要求该文件只解析一次,那么此时就能够把解析该文件的代码写到静态代码块当中了。测试

咱们来测试一下静态代码块:this

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);
	}
}
复制代码

运行结果以下图所示:spa

图1:静态代码块运行结果设计

经过以上的测试能够得知一个类当中能够编写多个静态代码块(尽管大部分状况下只编写一个),而且静态代码块遵循自上而下的顺序依次执行,因此有的时候放在类体当中的代码是有执行顺序的(大部分状况下类体当中的代码没有顺序要求,方法体当中的代码是有顺序要求的,方法体当中的代码必须遵照自上而下的顺序依次逐行执行),另外静态代码块当中的代码在main方法执行以前执行,这是由于静态代码块在类加载时执行,而且只执行一次。code

再来看一下如下代码:

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:测试工具类

相关文章
相关标签/搜索