static关键字的应用

一、静态属性

static是Java中常用的关键字,代表“全局”或者“静态”的意思。关于static的特征,可以理解为:方便在没有创建对象的情况下来进行某些操作。通常可用于修饰成员变量和方法,也可以形成静态代码块。

实际应用中,可将需频繁操作、通用型信息设置、公共组件封装等操作设置为“静态”。

应用一:static+成员变量 vs 成员变量

概念:

静态成员:用static修饰的成员变量,通常也成为静态成员、静态属性、类成员、全局属性等。

非静态成员:没有被static修饰的成员变量,也称为叫做非静态成员、实例变量,实例成员,对象成员、对象属性等。

特征:

静态成员:

  • 静态成员是属于整个类的,由类所进行维护,仅在类初次加载时会被初始化,在类销毁时回收。
  • 通过该类实例化的所有对象都共享类中静态资源,任一对象中信息的修订都将影响所有对象。
  • 由于静态成员在类加载期间就已经完成初始化,存储在Java Heap(JDK7.0之前存储在方法区)中静态存储区,因此优先于对象而存在,可以通过类名和对象名两种方式访问。

非静态成员:

  • 非静态成员属于对象独有,每个对象进行实例化时产生各自的成员,随着对象的回收而释放。
  • 对象对各自成员信息的修订不影响其他对象
  • 只能通过对象名访问。

应用:

可以将频繁调用的公共信息,期望加快运行焦虑的成员设置为静态。但需注意,由于其生命周期长,即资源占用周期长,要慎用。

示例:
定义国产车类CarDemo,分别包含静态属性firm,对象属性color、price
定义测试类CarTest,针对CarDemo进行测试
备注:暂不考虑属性的范围权限

public class CarDemo{
	static String firm;//厂商
	String color;//颜色
	int price;//价格

	public CarDemo(String color,int price){
		this.color = color;
		this.price = price;
	}

	//信息展示方法
	public void display(){
		//类内静态成员访问方式1:类名.成员名
		System.out.println("本款汽车信息展示:厂商--"+CarDemo.firm+",颜色--"+this.color+",价格--"+this.price);

		//类内静态成员访问方式2:this.成员名
		System.out.println("本款汽车信息展示:厂商--"+this.firm+",颜色--"+this.color+",价格--"+this.price);

		//类内静态成员访问方式3:成员名
		System.out.println("本款汽车信息展示:厂商--"+firm+",颜色--"+this.color+",价格--"+this.price);
	}
}
public class CarTest{
	public static void main(String[] args){
		//类外静态成员访问方式1:类名.成员名
		CarDemo.firm = "一汽集团";

		CarDemo one = new CarDemo("蓝色",200000);
		one.display();
		CarDemo two = new CarDemo("红色"1500000);
		two.display();

		//类外静态成员访问方式2:对象名.成员名
		two.firm = "上汽集团";

		one.display();
	}
}

此时输出结果为:

本款汽车信息展示:厂商--一汽集团,颜色--蓝色,价格--200000
本款汽车信息展示:厂商--一汽集团,颜色--红色,价格--150000
本款汽车信息展示:厂商--上汽集团,颜色--蓝色,价格--200000

总结:

  • 类外可应用“类名.成员名"或“对象名.成员名“的方式访问非私有静态成员,更推荐用”类名.成员名“体现其特性。应用”对象名.成员名“时会出现警告,但不影响程序运行。
  • 类内可应用”类名.成员名“或”this.成员名“的方式访问,应用”this.成员名“时会出现警告,但不影响程序运行。

二、静态方法

应用二:static+成员方法 vs 成员方法

概念:

静态方法:用static修饰的成员方法,通常也成为静态方法、类方法、全局方法等。

非静态方法:没有被static修饰的成员方法,也称为叫做非静态方法、实例方法、对象方法等。

特征:

与静态成员相似,静态方法属于整个类的,由类所进行维护,因此可以通过类名和对象名两种方式访问,也因此在静态方法中无法直接访问同类中的非静态成员。

总结:

1、静态方法中可以通过“类名.成员“或”成员”的方式访问类内静态成员/静态方法

2、不允许直接访问本类中的非静态成员/非静态方法

3、可以通过实例化产生本类对象,通过“对象.成员“的方式访问类内非静态成员/非静态方法。

4、类外可应用“类名.成员方法“或”对象名.成员方法“的方式访问非私有静态方法

5、应用”对象名.成员方法“时出现警告,但不影响程序运行。

6、非静态方法可以通过“类名.成员名“或”成员“或者“this.成员“的方式访问内静态成员/静态方法

7、应用”this.静态成员/静态方法“时会出现警告,但不影响程序运行。

8.不允许在方法内部定义静态局部变量。

三、静态代码块

应用三:static+代码块 vs 代码块

概念:

静态代码块:被static修饰的,定义在类内部,有{}括起来的代码段。

构造代码块:没有被static修饰的,定在在类内部,有{}括起来的代码段。

普通代码块:定在在方法内部,用{}扩起的代码段。

特征:

静态代码块:

  • 只能出现在类内,不允许出现在方法内。
  • 可以出现多次,按顺序在类加载时执行。
  • 无论该类实例化多好对象,只执行一次。

构造代码块:

  • 可以在类内出现多次,按顺序在每个对象实例化时执行。
  • 执行优先级:晚于静态代码块,高于构造方法。
  • 每次执行对象实例化时,均会执行一次。

普通代码块:

  • 可以在方法内出现多次,按顺序在方法调用时执行。

应用:

静态代码块:基于性能优先的考虑,多适用于需要在项目启动时执行一次的场景,譬如项目资源整体加载等。

构造代码块:多适用于类中每个对象产生时都是需要执行的功能封装。与构造方法的区别在于,构造方法时在new执行时有选择性的调用带參或者无參构造,而构造代码块则是,在每个对象实例化都一定会执行。

普通代码块:适用于在方法内进行代码功能拆分。

示例:
定义国产车类CarDemo,包含静态成员firm,非静态方法run;定义测试类CarTest,针对CarDemo进行测试。
备注:此处不考虑属性的访问权限

  • 当CarDemo类在静态代码块和构造代码块中分别对静态成员赋值,并添加构造方法
public class CarDemo{
	static String firm;//厂商

	static{
		firm = "一汽";
		System.out.println("我是静态代码块");
	}

	{
		firm = "东风";
		System.out.println("我是构造代码块");
	}

	public CarDemo(){
		System.out.println("我是构造方法");
	}

	public void run(){
		System.out.println("本款汽车信息展示:厂商--"+CarDemo.firm);
	}
}

测试类CarTest中实例化CarDemo,并调用run方法

public class CarTest{
	public static void main(String[] args){
		CarDemo one = new CarDemo();
		one.run();
		System.out.println("*****************");
		CarDemo two = new CarDemo();
		two.run();
	}
}

运行结果:

我是静态代码块
我是构造代码块
我是构造方法
本款汽车信息展示:厂商--东风
**************************
我是构造代码块
我是构造方法
本款汽车信息展示:厂商--东风

总结:
1、执行优先级:静态代码块>构造代码块>构造方法
2、执行次数:静态代码块只执行1次;构造代码块、构造方法随对象实例化个数而定

  • CarDemo类中添加成员属性color,并在静态代码块和构造代码块中分别对color进行赋值时
public class CarDemo{
	static String firm;
	String color;
	
	static{
		firm = "一汽";
		color = "蓝色";//错误提示:不能在静态块中操作非静态成员
		System.out.println("我是静态代码块");
	}

	{
		firm = "东风";
		color = "蓝色";
		System.out.println("我是构造代码块");
	}
}

总结:
1、不能在静态代码块中直接对非静态成员赋值
2、可以在构造代码块中直接操作静态和非静态成员。

  • 当将属性定义移入静态代码块时
public class CarDemo{
	static{
		static String firm = "一汽";//错误提示:不允许在静态代码块中声明静态成员;
		String color = "蓝色";
		System.out.println("我是静态代码块");
	}

	{
		firm = "东风";//错误提示:无法在构造代码块中访问到相关成员
		color = "红色";
		System.out.println("我是构造代码块");
	}
}

总结:
1、不能在静态代码块声明静态成员,可以声明局部变量。
2、静态代码块中声明的变量,在外部无法进行访问。

  • 当在run方法中分别添加2个代码块时
public class CarDemo{
	public void run(){
		int sum = 10;
		System.out.println("我是普通代码块1:"+sum);
	}
	{
		int sum = 20;
		System.out.println("我是普通代码块2:"+sum);
	}
}
public class CarTest{
	public static void main(String[] args){
		CarDemo one = new CarDemo();
		one.run();
	}
}

运行结果为:

我是普通代码块1:10
我是普通代码块2:20
  • 当在两个代码块上部添加同名局部变量声明时:
public class CarDemo{
	public void run(){
		int sum = 50;
		{
			int sum = 10;//错误提示:不允许定义重名变量
			System.out.println("我是普通代码块1:"+sum);
		}
		{
			int sum = 20;
			System.out.println("我是普通代码块2:"+sum);
		}
	}
}

总结:
1、普通代码块在方法内顺序执行,各自作用范围独立。
2、方法内定义的局部变量,作用范围为:自定义位置起,至方法结束。在此期间,不允许方法中普通代码块内存在局部变量的声明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值