## Java编程那些事儿65——static修饰符
郑州游戏学院陈跃峰
出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb)
### 8.7 修饰符
修饰符的作用是让被修饰的内容具备特定的功能,在程序中合理使用修饰符可以在语法和功能上实现很多需要的效果。Java语言中的修饰符主要有5个:static、final、native、abstract和synchronized。这里首先讲解static、final和native的作用。
#### 8.7.1 static修饰符
static关键字的中文意思是静态的,该修饰符可以修饰成员变量,成员常量和成员方法。使用该关键字修饰的内容,在面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,所以static修饰的成员变量一般称作类变量,而static修饰的方法一般称作类方法。另外,static还可以修饰代码块,下面进行详细的介绍。
##### 8.7.1.1 静态变量
static修饰的变量称作静态变量。静态变量和一般的成员变量不同,一个类在加载到内存时,静态变量只初始化一次,也就是说所有对象的静态变量在内存中都只有一个存储位置,每个对象中的静态变量都指向内存中同一个地址,它是在所有的对象之间共享的数据。另外静态变量在引用时比较方便。所以一般在需要实现以下两个功能时使用静态变量:
1. 在对象之间共享值时
2. 方便访问变量时
下面首先说一下非静态变量(没有static修饰符修饰的成员变量)在内存中如何存储的。示例代码如下:
~~~
//文件名Box.java
public class Box{
int length;
int width;
int height;
public Box(int l,int w,int h){
length = l;
width = w;
height = h;
}
}
//文件名TestBox.java
public class TestBox{
public static void main(String[] args){
Box a = new Box(10,20,30);
Box b = new Box(40,20,10);
}
}
~~~
则对象a和对象b在内存中的存储格式如下图所示:
对象a 对象b
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">10</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">20</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">30</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">length</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">width</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">height</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">40</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">20</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">10</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">length</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">width</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">height</font></span></p></div></td></tr></tbody></table>
从上面的图可以看出,非静态变量的值在每个对象中都有独立的存储空间,不同对象间这些值之间没有管理,也就是说每个对象都为内部的每个非静态的变量分配独立的存储空间,所以每个对象中非静态变量是隶属于对象,也就是说在每个对象中可能是不同的。
简单介绍了非静态变量在对象中的存储以后,下面再来看一下静态变量是如何进行存储的。示例代码如下:
~~~
//文件名StaticVar.java
public class StaticDemo{
static int m;
int n;
char c;
}
//文件名TestStaticVar.java
public class TestStaticVar{
public static void main(String[] args){
StaticVar sv1 = new StaticVar();
StaticVar sv2 = new StaticVar();
}
}
~~~
则对象sv1和对象sv2在内存中存储的格式如下图所示:
对象sv1 对象sv2
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">m</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">n</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">c</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">n</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">c</font></span></p></div></td></tr></tbody></table>
对于StaticDemo类型的对象sv1和sv2来说,由于使用默认的构造方法进行构造,所以每个成员变量都被初始化为对应数据类型的默认值,int的默认值为0,char的默认值为编号为0的字符,所以sv1和sv2对象中存储的值如上图所示。
而静态变量的存储和非静态变量的存储不同,在Java虚拟机内部,第一次使用类时初始化该类中的所有静态变量,以后就不再进行初始化,而且无论创建多少个该类的对象,静态变量的存储在内存中都是独立于对象的,也就是Java虚拟机单独为静态变量分配存储空间,所以导致所有的对象内部的静态变量在内存中存储时只有一个空间。这样就导致使用任何一个对象对该值的修改都是使该存储空间中的值发生改变,而其它对象在后续引用时就跟着发生了变化。静态变量就是使用这样的方式在所有的对象之间进行数值共享的。
静态变量在实际使用时,可以通过只存储一次来节约存储空间,这个特性导致在类内部定义的成员常量一般都做成静态的,因为常量的值在每个对象中都是相同的,而且使用static修饰也便于对成员常量的引用。
在类外部访问某类中静态变量(常量)的语法格式为:
类名.成员变量(常量)
例如:
StaticDemo.m
这样方便对于成员变量的访问。当然,语法上也不禁止使用:对象.成员变量,这样的语法格式进行访问,但是一般不推荐这样使用,而且有些类是无法创建对象的。
注意:static关键字不能修饰成员方法或构造方法内部的变量。
##### 8.7.1.2 静态方法
static修饰的方法称作静态方法。静态方法和一般的成员方法相比,不同的地方有两个:一是调用起来比较方便,二是静态方法内部只能使用静态的成员变量。所以一般静态方法都是类内部的独立的功能方法。例如为了方便方法的调用,Java API中的Math类中所有的方法都是静态的,而一般类内部的static方法也是方便其它类对该方法的调用。
示例代码如下:
~~~
//文件名MyMath.java
public class MyMath{
public static int max(int a,int b){
return (a > b ? a : b);
}
}
//文件名TestMyMath.java
public class TestMyMath{
public static void main(String[] args){
int m = 10;
int n = 20;
int k = MyMath.max(m,n);
}
}
~~~
静态方法在类的外部进行调用时不需要创建对象,使用类名.方法名(参数)这样的语法格式进行调研,简化了代码的编写。
使用静态方法时,需要特别注意的是静态方法内部使用该类的非静态成员变量,否则将出现语法错误。
静态方法是类内部的一类特殊方法,只有在需要时才将对应的方法声明成静态的,一个类内部的方法一般都是非静态的。
##### 8.7.1.3 静态代码块
静态代码块指位于类声明的内部,方法和构造方法的外部,使用static修饰的代码块。静态代码块在该类第一次被使用时执行一次,以后再也不执行。在实际的代码中,如果需要对类进行初始化的代码,可以写在静态代码块的内部。
示例代码如下:
~~~
//文件名StaticBlock.java
public class StaticBlock{
static{
System.out.println(“静态代码块!”);
}
}
~~~
静态代码块是一种特殊的语法,熟悉该语法的特点,在实际程序中根据需要使用。
- 前言
- (1)序言
- (2)程序设计是什么?
- (3)你适合学习程序设计吗?
- (4)如何学好程序设计?
- (5)程序设计介绍小结
- (6)计算机软件基本概念
- (7)进制的概念
- (8)计算机内部的数据表达
- (9)网络编程基础
- (10)Java语言简介
- (11)JDK的获得、安装和配置
- (12)第一个HelloWorld程序
- (13)Eclipse基本使用
- (14)Eclipse基础使用进阶
- (15)如何学好Java语法
- (16)代码框架、关键字和标识符
- (17)基本数据类型
- (18)变量和常量
- (19)数据类型转换
- (20)空白、语句结束和注释
- (21)算术运算符
- (22)比较运算符
- (23)逻辑运算符
- (24)赋值运算符
- (25)位运算符
- (26)移位运算符
- (27)其它运算符
- (28)运算符优先级
- (29)表达式
- (30)流程控制基础
- (31)if语句语法(1)
- (32)if语句语法(2)
- (33)if语句语法(3)
- (34)switch语句语法
- (35)while语句语法
- (36)do-while语句语法
- (37)for语句语法
- (38)break和continue语句
- (39)流程控制综合示例1
- (40)流程控制综合示例2
- (41)流程控制综合示例3
- (42)流程控制综合练习
- (43)数组概述
- (44)数组基础语法
- (45)数组使用示例1
- (46)数组使用示例2
- (47)数组使用示例3
- (48)多维数组基础
- (49)多维数组使用示例1
- (50)多维数组使用示例2
- (51)多维数组练习
- (52)方法声明
- (53)方法声明示例
- (54)方法调用
- (55)方法重载和参数传递
- (56)方法练习
- (57)面向对象基础
- (58)类(一)
- (59)类(二)
- (60)对象
- (61)面向对象设计方法和面向对象特性(一)
- (62)继承(二)
- (63)多态性
- (64)访问控制符、修饰符和其它关键字
- (65)static修饰符
- (66)final修饰符
- (67)this和super
- (68)抽象类和接口(一)
- (69)抽象类和接口(二)
- (70)抽象类和接口(三)
- (71)内部类简介
- (72)包的概念
- (73)JDK文档使用
- (74)java.lang包介绍1
- (75)String类使用
- (76)StringBuffer类和System类
- (77)包装类
- (78)时间和日期处理
- (79)Random随机处理
- (80)集合框架简述
- (81)异常处理概述
- (82)异常处理语法1
- (83)异常处理语法2
- (84)IO简介
- (85)IO类体系
- (86)文件操作之File类使用
- (87)文件操作之读取文件
- (88)文件操作之写文件
- (89)读取控制台输入
- (90)装饰流使用1
- (91)装饰流使用2
- (92)IO使用注意问题
- (93)多线程基础
- (94)多线程实现方式1
- (95)多线程实现方式2
- (96)多线程使用示例1
- (97)多线程使用示例2
- (98)多线程问题及处理1
- (99)多线程问题及处理2
- (100)多线程问题及处理3
- (101)网络编程概述
- (102)网络编程技术1
- (103)网络编程技术2
- (104)网络编程技术3
- (105)网络编程技术4
- (106)网络编程技术5
- (107)网络协议概念
- (108)网络编程示例1
- (109)网络编程示例2
- (110)网络编程小结