Java static关键字使用小结
2016-03-11 00:33
507 查看
static修饰类变量和方法
static关键字最常见的用法就是用来修饰类的成员变量和方法。这样创建出的成员变量属于类而非具体的实例,这种用法不再详述。需要注意的是类方法不能访问instance变量和方法,类方法中不能使用this关键字。
static修饰常量
static结合final用来定义常量,例如:static final double PI = 3.141592653589793;
需要注意的是,定义的常量是基本类型(primitive type)或者字符串类型(String),这种常量是编译器常量(compile-time constant),如果引用外部的编译期常量并且该常量值发生变化,需要对引用外部常量的类重新编译。
static修饰内嵌类
Java内嵌类分为静态内嵌类(nested class)和非静态内嵌类,其中非静态内嵌类也叫内部类(inner class).不同于内部类(内部类不能定义静态成员),静态内嵌类不能访问外部类的成员。
静态内嵌类实例化:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
内部类实例化(先必须创建出外部类实例):
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
static修饰import
为了避免访问其他类的静态成员时必须使用类名来引用,例如double r = Math.cos(Math.PI * theta);,可以用static import:
import static java.lang.Math.PI; double r = cos(PI * theta);
static import声明不应当被滥用,否则会使代码难于阅读和维护,仅仅在经常使用的静态成员上使用static import。
static修饰代码块
什么是static block
static修饰的代码是类的初始化代码块,没有static关键字修饰的是实例初始化代码块。类的初始化代码块在类第一次被加载时(被Resolve时)按照代码块定义的顺序执行,由于Java代码是按需加载,有可能被引用类的初始化代码块不会被执行(参见后面的例子)。
public class StaticExample{ static { System.out.println("This is first static block"); } public StaticExample(){ System.out.println("This is constructor"); } public static String staticString = "Static Variable"; static { System.out.println("This is second static block and " + staticString); } public static void main(String[] args){ System.out.println("====main start...==="); StaticExample statEx = new StaticExample(); StaticExample.staticMethod2(); } static { staticMethod1(); System.out.println("This is third static block"); } public static void staticMethod1() { System.out.println("This is static method1"); } public static void staticMethod2() { System.out.println("This is static method2"); } }
以上代码的执行结果,请注意其中static block和main函数以及本类自己的构造函数的执行顺序:
This is first static block This is second static block and Static Variable This is static method1 This is third static block ====main start...=== This is constructor This is static method2
实例的初始化代码块是当被类实例化时执行,并且执行的时机是在父类构造函数执行完毕,自己的构造函数执行之前。
public class ConstructorBlockExample{ { System.out.println("This is first constructor block"); } public ConstructorBlockExample(){ System.out.println("This is no parameter constructor"); } public ConstructorBlockExample(String param1){ System.out.println("This is single parameter constructor"); } public ConstructorBlockExample(String param1, String param2){ System.out.println("This is two parameters constructor"); } { System.out.println("This is second constructor block"); } public static void main(String[] args){ ConstructorBlockExample constrBlockEx = new ConstructorBlockExample(); ConstructorBlockExample constrBlockEx1 = new ConstructorBlockExample("param1"); ConstructorBlockExample constrBlockEx2 = new ConstructorBlockExample("param1", "param2"); } }
以上代码的执行结果,请注意其中非static block和几个构造函数的执行顺序,每一次实例化构造函数执行前,非static block的代码均会被执行:
This is first constructor block This is second constructor block This is no parameter constructor This is first constructor block This is second constructor block This is single parameter constructor This is first constructor block This is second constructor block This is two parameters constructor
static block的用途
实现一个线程安全的单例Singleton
public class Singleton { private static final Singleton instance; static { try { instance = new Singleton(); } catch (Exception e) { throw new RuntimeException("Darn, an error occurred!", e); } } public static Singleton getInstance() { return instance; } private Singleton() { // ... } }
实现全局注册信息的初始化
在Android 6.0的framework代码中,一大部分系统服务的注册由新增加的SystemServiceRegistry类来管理,在该类中使用的静态代码块实现了类加载时就注册好所管理的系统服务信息:(frameworks/base/core/java/android/app/SystemServiceRegistry.java)
final class SystemServiceRegistry { 127 private final static String TAG = "SystemServiceRegistry"; 128 ... 139 140 static { 141 registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, 142 new CachedServiceFetcher<AccessibilityManager>() { 143 @Override 144 public AccessibilityManager createService(ContextImpl ctx) { 145 return AccessibilityManager.getInstance(ctx); 146 }}); 147 148 registerService(Context.CAPTIONING_SERVICE, CaptioningManager.class, 149 new CachedServiceFetcher<CaptioningManager>() { 150 @Override 151 public CaptioningManager createService(ContextImpl ctx) { 152 return new CaptioningManager(ctx); 153 }}); ...
Reference
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.htmlhttp://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class
http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html
http://stackoverflow.com/questions/2943556/static-block-in-java
https://en.wikipedia.org/wiki/Singleton_pattern
http://www.jusfortechies.com/java/core-java/static-blocks.php
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
相关文章推荐
- JAVA工程师成神之路
- ubuntu下安装、配置JDK8
- 【图】解类似MyEclipse查看原始类出现”The JAR file dom4j-1.6.1jar has no source attachment”的问题
- 冒泡排序--Java实现
- Java入门 之深入浅出吧
- java中静态代码块的用法 static用法详解和static静态导入
- [Java开发之路](20)try-with-resource 异常声明
- spring aop 基于xml配置版
- 1.java开篇
- Struts 1或2 ActionForm接受不到页面传值的问题
- 单点登录研究一
- JavaWeb学习(二):Servlet
- JavaWeb学习(三):jsp
- JavaWeb学习(一):Servlet
- RxJava学习历程(二)
- java基础
- Spring中ref
- Missing artifact javax.jms:jms:jar:1.1:compile
- JAVA泛型方法
- Zookeeper的安装和配置