admin管理员组

文章数量:1031680

Java基础:static的理解(含义、用法及静态修饰的优先顺序)

前言:

在java的关键字中,static和final是两个我们必须掌握的关键字。不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。我们经常见到static,例如每个main方法都会被标记为static修饰符,下面我们先来了解一下static关键字及其用法。

static关键字

一、静态域     如果将域(属性)定义为static,每个类中只有一个这样的域。而每一个对象对于所有的实例却都有自己的一份拷贝。

例如:假定需要给每一个雇员赋予唯一的标志码。这里给Employee类添加一个实例域id和一个静态域nextId。

代码示例:

代码语言:javascript代码运行次数:0运行复制
class Employee{
	private static int nextId = 1;
	private int id;
	...
}

    现在每个雇员都有一个自己的id域,但这个类的所有实例将共享一个nextId域。换句话说,如果有1000个Employee类的对象,则有1000个实例域id,但只有一个静态域nextId 。

我们从内存看一下原因:

从内存理解可以清楚的看出static的作用,另外我们要知道,即使没有一个雇员对象,静态域nextId也已经存在。即它属于类,而不属于任何独立的对象,不属于实例。 static类型在实例化创建的时候不会新建,节省内存,但是有一个实例改变他的值,所以的实例里面都会对应修改,如果不想被修改,应该用final修饰。

二、静态常量 静态变量使用的比较少,但静态常量却使用得比较多。这里就不做赘述。

三、静态方法     静态方法是一种不能向对象实施操作的方法。静态方法可以访问自身类中的静态域。

下面我们看代码1:

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}
代码语言:javascript代码运行次数:0运行复制
package practice6;

public class Test4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Employee3 a = new Employee3();	
	}
}

运行结果:

解释: 这里我们似乎可以看到,静态初始化块都先输出了,因为被static修饰,即使没有实例化对象,也已经存在,但是静态初始化块修饰的无论是什么情况下都会优先输出吗???目前的代码似乎是这个意思。

下面我们再看一下更改的代码2: 实例化一个静态方法Employee3,其他不变

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	//我们在这里实例化了一个静态Employee3方法
	private static Employee3 as32 = new Employee3();
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}

运行结果:

这里我们发现并不是所有被static修饰的都会优先输出,为什么???

解释: 首先我们看到运行结果,第一行静态初始化块1在函数的最顶部,所以优先加载出来,然后第二、三行加载的静态初始化块和构造方法,第四行开始实际是加载实例化静态方法Employee3的,由于static修饰的只会加载一次,所以static修饰的尽量会在实例化静态方法Employee3中才加载靠后输出。


下面我们再看一下更改的代码3: 在static修饰的方法里面实例化一个Employee3,其他不变

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
		Employee3 as = new Employee3(); //改变所在行
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	private static Employee3 as32 = new Employee3();	
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}

运行结果:

解释: 这里我们只解释一下为什么第一个输出的非静态初始化块的nextId 值为0,我们明明给nextId 赋值为90了啊。 这就是受static修饰的不论被实例化多少次,只会加载一次的影响,我们是这样定义的:private static int nextId = 90; 既然nextId 被static修饰,那么执行as 方法的时候会先跳过去执行非静态方法,所以调用nextId 时,会使用nextId 的默认值,int的默认值是0。

总结

Java中static的含义和用法: static:静态的,用于修饰成员(成员变量,成员方法);

1.被static所修饰的变量或者方法会储存在数据共享区;

2.被static修饰后的成员变量只有一份!

3.当成员被static修饰之后,就多了一种访问方式,除了可以被对象调用之外,还可以直接 被类名调用,(类名.静态成员);

4.static的特点: a.随着类的加载而被加载; b.优先于对象存在; c.被所有对象共享;

5.被static修饰的变量成为静态变量(类变量)或者实例变量;

6.存放位置 a.类变量随着类的加载而存在于date内存区; b.实例变量随着对象的建立而存在于堆内存;

7.生命周期: a.类变量周期生命最长,随着类的消失而消失; b.实例变量生命周期比类变量短,它是随着对象的消失而消失;

8.方法注意事项: a.静态的方法只能访问静态的成员; b.非静态得方法即能访问静态得成员(成员变量,成员方法)又能访问非静态得成员; c.局部变量不能被static修饰; d.静态得方法中是不可以定义this、super关键字的,因为静态优先于对象存在,所以静态方法不可以出this;

9.什么时候使用static修成员: 当属于同一个类的所有对象出现共享数据时,就需要将存储这个共享数据的成员用static修饰;

10.什么时候使用static修饰方法: 当功能内部没有访问到非静态的成员时(对象特有的数据)那么该功能可以定义成静态的.

注意:

  1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
  2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-07,如有侵权请联系 cloudcommunity@tencent 删除static变量对象基础java

Java基础:static的理解(含义、用法及静态修饰的优先顺序)

前言:

在java的关键字中,static和final是两个我们必须掌握的关键字。不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。我们经常见到static,例如每个main方法都会被标记为static修饰符,下面我们先来了解一下static关键字及其用法。

static关键字

一、静态域     如果将域(属性)定义为static,每个类中只有一个这样的域。而每一个对象对于所有的实例却都有自己的一份拷贝。

例如:假定需要给每一个雇员赋予唯一的标志码。这里给Employee类添加一个实例域id和一个静态域nextId。

代码示例:

代码语言:javascript代码运行次数:0运行复制
class Employee{
	private static int nextId = 1;
	private int id;
	...
}

    现在每个雇员都有一个自己的id域,但这个类的所有实例将共享一个nextId域。换句话说,如果有1000个Employee类的对象,则有1000个实例域id,但只有一个静态域nextId 。

我们从内存看一下原因:

从内存理解可以清楚的看出static的作用,另外我们要知道,即使没有一个雇员对象,静态域nextId也已经存在。即它属于类,而不属于任何独立的对象,不属于实例。 static类型在实例化创建的时候不会新建,节省内存,但是有一个实例改变他的值,所以的实例里面都会对应修改,如果不想被修改,应该用final修饰。

二、静态常量 静态变量使用的比较少,但静态常量却使用得比较多。这里就不做赘述。

三、静态方法     静态方法是一种不能向对象实施操作的方法。静态方法可以访问自身类中的静态域。

下面我们看代码1:

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}
代码语言:javascript代码运行次数:0运行复制
package practice6;

public class Test4 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Employee3 a = new Employee3();	
	}
}

运行结果:

解释: 这里我们似乎可以看到,静态初始化块都先输出了,因为被static修饰,即使没有实例化对象,也已经存在,但是静态初始化块修饰的无论是什么情况下都会优先输出吗???目前的代码似乎是这个意思。

下面我们再看一下更改的代码2: 实例化一个静态方法Employee3,其他不变

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	//我们在这里实例化了一个静态Employee3方法
	private static Employee3 as32 = new Employee3();
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}

运行结果:

这里我们发现并不是所有被static修饰的都会优先输出,为什么???

解释: 首先我们看到运行结果,第一行静态初始化块1在函数的最顶部,所以优先加载出来,然后第二、三行加载的静态初始化块和构造方法,第四行开始实际是加载实例化静态方法Employee3的,由于static修饰的只会加载一次,所以static修饰的尽量会在实例化静态方法Employee3中才加载靠后输出。


下面我们再看一下更改的代码3: 在static修饰的方法里面实例化一个Employee3,其他不变

代码语言:javascript代码运行次数:0运行复制
package practice6;
public class Employee3 {	
	static{
		System.out.println("这是静态初始化块1");
		Employee3 as = new Employee3(); //改变所在行
	}
	private static int nextId = 90;
	private int id;
	private String name = "巴啦啦";
	private double salary;
	private static Employee3 as32 = new Employee3();	
	{
		System.out.println("这是非静态初始化块:" + nextId + "==name:" + name);
		id = nextId;
		nextId++;
	}	
	static{
		System.out.println("这是静态初始化块2:" + nextId);		
	}
	public Employee3(String n ,double s) {
		name = n;
		salary = s;
	}
	public Employee3() {		
		System.out.println("这是构造方法");
		name = "";
		salary = 0;
	}	
}

运行结果:

解释: 这里我们只解释一下为什么第一个输出的非静态初始化块的nextId 值为0,我们明明给nextId 赋值为90了啊。 这就是受static修饰的不论被实例化多少次,只会加载一次的影响,我们是这样定义的:private static int nextId = 90; 既然nextId 被static修饰,那么执行as 方法的时候会先跳过去执行非静态方法,所以调用nextId 时,会使用nextId 的默认值,int的默认值是0。

总结

Java中static的含义和用法: static:静态的,用于修饰成员(成员变量,成员方法);

1.被static所修饰的变量或者方法会储存在数据共享区;

2.被static修饰后的成员变量只有一份!

3.当成员被static修饰之后,就多了一种访问方式,除了可以被对象调用之外,还可以直接 被类名调用,(类名.静态成员);

4.static的特点: a.随着类的加载而被加载; b.优先于对象存在; c.被所有对象共享;

5.被static修饰的变量成为静态变量(类变量)或者实例变量;

6.存放位置 a.类变量随着类的加载而存在于date内存区; b.实例变量随着对象的建立而存在于堆内存;

7.生命周期: a.类变量周期生命最长,随着类的消失而消失; b.实例变量生命周期比类变量短,它是随着对象的消失而消失;

8.方法注意事项: a.静态的方法只能访问静态的成员; b.非静态得方法即能访问静态得成员(成员变量,成员方法)又能访问非静态得成员; c.局部变量不能被static修饰; d.静态得方法中是不可以定义this、super关键字的,因为静态优先于对象存在,所以静态方法不可以出this;

9.什么时候使用static修成员: 当属于同一个类的所有对象出现共享数据时,就需要将存储这个共享数据的成员用static修饰;

10.什么时候使用static修饰方法: 当功能内部没有访问到非静态的成员时(对象特有的数据)那么该功能可以定义成静态的.

注意:

  1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
  2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-07,如有侵权请联系 cloudcommunity@tencent 删除static变量对象基础java

本文标签: Java基础static的理解(含义用法及静态修饰的优先顺序)