Java Static关键字详解
提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的,但是像这样的基础不牢的人应该不少,因为常用,所以用大家都会,但是谈到精细之处都够呛。这篇博客是我翻出我原来的学习笔记再加上自己看的一些博客整理出来的,供基础知识不怎么牢靠的同学参考参考。
1. static 关键字要解决的问题
这里摘录一下《Java编程思想(第四版)》里关于static关键字的一段原话:(P29)通常来说,当创建类时,就是在描述那个类的对象的外观与行为。除非用new创建那个对象,否则,实际上并未获得任何对象。执行new来创建对象的时候,数据存储空间才被分配,其方法才供外界调用。有两种情形用上述方法是无法解决的。一种情形是,只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少个对象,甚至根本不需要创建任何对象。另一种情形是,希望某个方法不与包含他的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用方法。简单来说,static的主要目的就是创建独立于具体对象的域变量与方法。
2. static修饰的变量或方法或类的加载时机
在加载类的同时加在static修饰的部分。(注意:这个时候,还不存在具体对象,并且这个过程只进行一次)
3. 通过代码示例来分别看看静态变量、静态方法、静态类的效果
3.1 静态变量
public class StaticTest{public static int count =0;@SuppressWarnings("static-access")public static void main(String[] args) {// TODO Auto-generated method stubStaticTest test1 = new StaticTest();System.out.println(test1.count);StaticTest test2 = new StaticTest();test2.count++;System.out.println(test1.count+" "+test2.count+" "+StaticTest.count);}}
输出结果:
0 1 1 1
可见,static变量并不是所在类的某个具体对象所有,而是该类的所有对象所共有的,静态变量既能被对象调用,也能直接拿类来调用。
除此之外,静态变量不能引用非静态方法,原因正如前面描述静态加载时机中说的那样,加载静态的时候,非静态的变量、方法等还不存在,当然就无法引用了。但是,非静态方法或类却能正常引用静态变量或方法。因为非静态总是在静态之后出现的。
3.2 静态方法
静态方法和静态变量一样,属于类所有,在类加载的同时执行,不属于某个具体的对象,所有对象均能调用。对于静态方法需要注意以下几点:
- 它们仅能调用其他的static 方法。
- 它们只能访问static数据。
- 它们不能以任何方式引用this 或super。
class Simple {static void go() {System.out.println("Welcome");} }public class Cal {public static void main(String[] args) {Simple.go();} }
静态方法一般用于工具类中,可以直接拿类名调用工具方法进行使用。
3.3 静态类
一般来说,一个普通类是不允许被声明为static的,但是,在内部类中可以将其声明为static的,这个时候,外部类可以直接调用内部类,因为static的内部类是在加载外部类的同时加载的,所以也就是说,并不要实例化外部类就能直接调用静态内部类。看例子:
public class BaseStatic {static {System.out.println("Load base static");}public BaseStatic(){System.out.println("BaseStatic constructor");}static class BaseInnerClass{static{System.out.println("Base inner class static");}public BaseInnerClass(){System.out.println("BaseInnerClass constructor");}}}public class StaticLoadOrderTest{public static void main(String[] args) {// TODO Auto-generated method stubnew BaseStatic.BaseInnerClass();}}
在看答案之前,自己想想这个输出结果是什么?
先不急着看答案,我们先来看看这个执行过程:首先,在进入StaticLoadOrderTest的main方法之前,加载StaticLoadOrderTest类,然后执行new BaseStatic.BaseInnerClass();这里需要注意:因为BaseInnerClass是静态的,所以这里并不需要加载外部类和实例化外部类,可以直接加载BaseInnerClass并实例化。所以输出:
Base inner class static BaseInnerClass constructor
这里留个坑:当直接使用外部类类名.静态内部类进行实例化的时候,如果外部类没有加载的话(实际上也是没有加载),那么这个statement: BaseStatic.BaseInnerClass中的BaseStatic是个什么存在????难道只是与静态内部类发生了简单的名称关联吗?若是这样还设计静态内部类干嘛呢?我觉得java设计者们不至于犯这种错误吧?也可能因为自己对于JVM并不熟悉,对于底层不太了解,若是路过的大神能帮忙解决一下,感激不尽!!!!
3.4 关于静态加载顺序的示例
下面这段代码的输出是什么?
public class BaseStatic {static {System.out.println("Load base static");}public BaseStatic(){System.out.println("BaseStatic constructor");}static class BaseInnerClass{static{System.out.println("Base inner class static");}public BaseInnerClass(){System.out.println("BaseInnerClass constructor");}}}public class StaticLoadOrderTest {static {System.out.println("Load test");}public StaticLoadOrderTest(){System.out.println("Test constructor");}public static void main(String[] args) {// TODO Auto-generated method stubnew BaseStatic();new StaticLoadOrderTest();new BaseStatic.BaseInnerClass();}}
和上面一样,分析一下过程:在进入main方法之前,需要加载StaticLoadOrderTest类,这时候发现有static代码块,先加载静态代码块,然后进入main方法内部,new BaseStatic(),这时候需要加载BaseStatic类,同时也要先加载静态代码块,然后调用构造器。注意:这里并没有加载BaseInnerClass,因为它是内部类只有在真正用到的时候才会进行加载,相信聪明的读者看到这个是不是想到了又一种单例设计模式的实现方式?自己研究吧。回到main方法中,接下来该执行new StaticLoadOrderTest()了,因为StaticLoadOrderTest类之前已经被加载过一次了,并且类只加载一次,所以这里就直接构造了;然后是最后一句new BaseStatic.BaseInnerClass()了,和上面例子一样,这里就不再细讲。所以输出结果为:
Load test Load base static BaseStatic constructor Test constructor Base inner class static BaseInnerClass constructor
再考虑一下,如果我把上面的例子改成下面这样,输出结果又会是什么呢?
public class BaseStatic {static {System.out.println("Load base static");}public BaseStatic(){System.out.println("BaseStatic constructor");}static class BaseInnerClass{static{System.out.println("Base inner class static");}public BaseInnerClass(){System.out.println("BaseInnerClass constructor");}}}public class StaticLoadOrderTest extends BaseStatic{static {System.out.println("Load test");}public StaticLoadOrderTest(){System.out.println("Test constructor");}public static void main(String[] args) {// TODO Auto-generated method stubnew BaseStatic.BaseInnerClass();new StaticLoadOrderTest(); new BaseStatic();}}
以上就是关于java中static关键字的一些知识了。
最后,预祝国足世预赛四强赛首站告捷!��������
码字不易,请尊重原创,转载请注明出处。
参考资料:
http://yongliang567.iteye.com/blog/904467
http://blog.csdn.net/anmei2010/article/details/4096131
http://blog.csdn.net/brouth/article/details/51656603
《Java编程思想(第四版)》
Java Static关键字详解相关推荐
- [转载] Java static关键字详解
参考链接: Java中的static关键字 static关键字 在类中,用static声明的成员变量为静态成员变量,也成为类变量.类变量的生命周期和类相同,在整个应用程序执行期间都有效. 这里要强调一 ...
- Java中的static关键字详解
** Java中的static关键字详解 ** 在一个类中定义一个方法为static,即静态的,那就是说无需本类的对象就可以调用此方法.调用一个静态方法就是 "类名.方法名" ,静 ...
- Day16-01 P71 面向对象12什么是多态 P72 对象13:instanceof和类型转换 P73 static关键字详解 P74 抽象类 P75 接口的定义与实现 P76N种内部类
Day16-01 P71 面向对象12:什么是多态 //父类Person package com.oop.demo06;public class Person {public void run(){S ...
- 在 C/C++中 static 关键字详解
static 关键字详解 C/C++ 中的 static 1. 静态局部变量 2. 静态全局变量 全局变量 与 extren 3. static 修饰函数 C++的 static 成员 静态成员变量 ...
- C/C++程序内存布局(data段,bss段,text段)以及static关键字详解
目录 1.内存布局 1.1 data段(可读可写) 1.2 text段(只读) 1.3 bss段(可读可写) 1.4 堆区 1.5 栈区 1.6全局区/静态区 1.7 字符串常量区 1.8 代码区 1 ...
- C/C++中static关键字详解
其实只有一句话需要注意: static在类外初始化,然后才可以在类内修改,其生命周期就是整个程序的生命周期. 静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时 ...
- Java instanceof关键字详解
严格来说 instanceof 是 Java 中的一个双目运算符,由于它是由字母组成的,所以也是 Java 的保留关键字.在 Java 中可以使用 instanceof 关键字判断一个对象是否为一个类 ...
- C语言中static关键字详解
C语言中staic关键字很简单,简单到你的任何一个项目中可以不写一个staic关键字也是没有问题的.写这篇章主要是一下自己的staic的理解和应用,当然在章开头依旧要照本宣科简述一下static关键字 ...
- C语言之static关键字详解
目录 前言: 一.几个概念 1.变量 2.局部变量和全局变量 3.变量的作用域 4.变量的生命周期 二.static关键字的作用 三.static关键字修饰局部变量 四.static关键字修饰全局变量 ...
- day28 static关键字详解 static在代码中的顺序
static关键字 static的优先级: 随着类的加载一起存在. static的优势: 可以直接用 不通过new,也可以直接通过类调用 static的缺点: 不可以被方法重写. static在代码中 ...
最新文章
- java高深技术总结_一名25K以上的高薪Java程序员总结出的技术以及学习技能
- Python实现信息自动配对爬虫排版程序
- VTK:Filtering之ImplicitBoolean
- python异常(高级) Exception
- 字符串php手册,php知识点复习之字符串
- 潜伏者与谍报密码(洛谷P1071题题解,Java语言描述)
- 期刊 | 人类遗传学领域期刊速览
- lighthouse_如何提高您的渐进式网络应用的Google Lighthouse得分(最高可达100分)
- 打印图形 字母倒三角
- 多维数组做参数,内存可以看做是线性的
- linux 建立vnc,51CTO博客-专业IT技术博客创作平台-技术成就梦想
- Java核心技术笔记 1
- Mac工具PullTube如何在下载列表中创建重复项
- 用逻辑门设计一个CPU
- cad怎么卸载干净_安装CAD时提示已安装了怎么办?收藏了这个方法,节省你半天时间!...
- 这十年,阿里开发者毕玄的日常
- Win7开自带的虚拟WIFI
- 成都盛迈坤电商:店铺有效评价要怎么进行提升
- word 加载MathType打开时显示“安全警告,宏已被禁用”解决办法
- Linux修改localhost