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修饰方法: 当功能内部没有访问到非静态的成员时(对象特有的数据)那么该功能可以定义成静态的.
注意:
- 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
- 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
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修饰方法: 当功能内部没有访问到非静态的成员时(对象特有的数据)那么该功能可以定义成静态的.
注意:
- 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
- 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
本文标签: Java基础static的理解(含义用法及静态修饰的优先顺序)
版权声明:本文标题:Java基础:static的理解(含义、用法及静态修饰的优先顺序) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/jiaocheng/1747869755a2220307.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论