Java知识碎片整理(5)——static关键字与单例设计模式
2016-10-28 00:26
429 查看
static——2016/10/28
单例模式——2017/1/13
修饰静态方法,或者叫实用用法(utility method)
静态变量:
静态变量是一个类的共有性质:all objects of one class share same static fields.一个实例的静态变量变化,这个类的其他实例的该变量同时发生变化。
静态方法是通过类而非类的对象调用的方法,最典型的例子是Math类:
以及单例设计模式的类实例化方法:
完整的例子应该是这样的:
下面的例子来说明问题:
输出是:
1、每调用一次构造方法,则执行一次构造块
2、静态块只在类加载的时候加载一次
3、有多个静态变量或块时,按声明顺序加载
通过这样的设计,可以设定一个类只有一个实例化,这样的设计方法也叫做单例模式。这样的功能实际上也可以使用一个int型数字作为标记,然后可以是一个类实例化不超过一个或几个,但显然使用static更高端一点。
但这个设计存在一个漏洞,那就是公共实例方法不是同步方法,这意味着,如果多个线程调用这个方法,可能会出现创建了多个实例的错误情况。使用synchronized关键字,加强上述代码:
上述代码演示的都是“懒汉式”单例模式,还有一种“恶汉式”单例模式,两者区别在于:
懒汉式:在声明私有静态的类对象,初始设置为空;
饿汉式:在类中声明静态类对象时直接初始化了一个实例。
这样做确保了一定只有一个实例,安全性更有保障,但较比懒汉式存在一个问题,就是在未使用的时候,就消耗了空间,如果这个类包含很多属性,这个消耗就值得优化。因此有了下面的小改良:
把实例包装在一个私用的工具类里面,这样在类中只有一个工具类的引用,只有在真正外部实例化的时候,才会开辟空间,创建类的实际对象。代码又一次提升了。
单例模式——2017/1/13
static关键字用途:
修饰静态变量修饰静态方法,或者叫实用用法(utility method)
静态变量:
静态变量是一个类的共有性质:all objects of one class share same static fields.一个实例的静态变量变化,这个类的其他实例的该变量同时发生变化。
静态方法是通过类而非类的对象调用的方法,最典型的例子是Math类:
double x=Math.sqrt(3.9);
以及单例设计模式的类实例化方法:
public static classname getInstance()
完整的例子应该是这样的:
static的加载与执行
实际上,静态变量与静态方法使用的不同只是表象,本质是static修饰符改变了代码的加载时机。下面的例子来说明问题:
public class StaticClass { static{ System.out.println("run1"); } public StaticClass(){ System.out.println("init"); } static{ System.out.println("run2"); } public static void main(String[] args) { StaticClass sc=new StaticClass(); } }
输出是:
run1 run2 init
1、每调用一次构造方法,则执行一次构造块
2、静态块只在类加载的时候加载一次
3、有多个静态变量或块时,按声明顺序加载
通过static关键词实现单例设计模式
/** * 演示单例设计模式 * @author reus * 1,私有化构造器,避免外部直接创建 * 2,声明私有静态的类对象,初始设置为空 * 3,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 */ public class Singleton { //1,私有化构造器,避免外部直接创建 private Singleton(){ } //2,声明私有静态的类对象,初始设置为空 private static Singleton instance=null; //3,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 public static Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; } } public class test { public static void main(String[] args) { Singleton s1=Singleton.getInstance();//调用getInstance()实例化 Singleton s2=Singleton.getInstance(); System.out.println(s1==s2);//通过输出可以看到实际上s1和s2是同一个对象 } }
通过这样的设计,可以设定一个类只有一个实例化,这样的设计方法也叫做单例模式。这样的功能实际上也可以使用一个int型数字作为标记,然后可以是一个类实例化不超过一个或几个,但显然使用static更高端一点。
但这个设计存在一个漏洞,那就是公共实例方法不是同步方法,这意味着,如果多个线程调用这个方法,可能会出现创建了多个实例的错误情况。使用synchronized关键字,加强上述代码:
/** * 演示单例设计模式 * @author reus * 1,私有化构造器,避免外部直接创建 * 2,声明私有静态的类对象,初始设置为空 * 3,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 * *用synchronized关键词强化安全性 */ public class Singleton { //1,私有化构造器,避免外部直接创建 private Singleton(){ } //2,声明私有静态的类对象,初始设置为空 private static Singleton instance=null; //3,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 public static Singleton getInstance(){ if(instance==null){//已经有实例,直接返回,提高效率 synchronized (Singleton.class) {//*用synchronized关键词强化安全性 if(instance==null){//确保安全性 instance=new Singleton(); } } } return instance; } }
上述代码演示的都是“懒汉式”单例模式,还有一种“恶汉式”单例模式,两者区别在于:
懒汉式:在声明私有静态的类对象,初始设置为空;
饿汉式:在类中声明静态类对象时直接初始化了一个实例。
/** * 演示单例设计模式 * @author reus * 1,饿汉式实现:在类中声明静态类对象时直接初始化了一个实例 * 2,在对外的实例方法中,直接返回已实例化对象 */ class Singleton2 { private Singleton2(){ } //1,声明私有静态的类对象——饿汉式实现:在类中声明静态类对象时直接初始化了一个实例 private static Singleton2 instance=new Singleton2(); //2,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 public static Singleton2 getInstance(){ return instance; } }
这样做确保了一定只有一个实例,安全性更有保障,但较比懒汉式存在一个问题,就是在未使用的时候,就消耗了空间,如果这个类包含很多属性,这个消耗就值得优化。因此有了下面的小改良:
/** * 演示单例设计模式 * @author reus * 1,饿汉式实现:在类中声明静态类对象时直接初始化了一个实例 * 2,在对外的实例方法中,直接返回已实例化对象 * **把实例包装在一个类里面,这样在Singleton只有一个SingletonHolder类的引用,、 * **只有在真正外部实例化的时候,才会开辟空间,创建单例的对象 */ class Singleton3 { //**把实例包装在一个类里面,这样在Singleton只有一个SingletonHolder类的引用,只有在真正外部实例化的时候,才会开辟空间,创建单例的对象 private static class Singleton3Holder{ //1,声明私有静态的类对象——饿汉式实现:在类中声明静态类对象时直接初始化了一个实例 private static Singleton3 instance=new Singleton3(); } private Singleton3(){ } //2,创建对外的静态方法,判断对对象是否为空,如果为空,调用私有的创建方法 public static Singleton3 getInstance(){ return Singleton3Holder.instance; } }
把实例包装在一个私用的工具类里面,这样在类中只有一个工具类的引用,只有在真正外部实例化的时候,才会开辟空间,创建类的实际对象。代码又一次提升了。
相关文章推荐
- java基础知识记录--软件工程与设计模式(摘自张孝祥整理java面试题)
- 关于java中static关键字在单态设计模式的应用学习和总结
- Java笔记2 面向对象<2>static关键字、main函数、静态运用、单例设计模式
- 黑马程序员 Java基础 面向对象:static关键字 main函数 单例设计模式
- Java基础(面向对象二——static关键字、主函数定义和单例设计模式)
- 黑马程序员——Java基础:static关键字、单例设计模式
- java基础之equal()方法、static关键字、单例设计模式
- 设计模式一--单例模式(java static等知识)
- Java_static 关键字, 单例设计模式
- java--整理下关于static关键字的知识
- 设计模式--模板方法模式--Java实现-- java访问控制关键字用法
- 方法的重载与重写的关系(区别);static关键字;单例设计模式;继承;
- JAVA关键字整理:static & final & native
- Java设计模式之代理模式_动力节点Java学院整理
- Java设计模式之命令模式_动力节点Java学院整理
- Java设计模式之观察者模式_动力节点Java学院整理
- 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结
- Java设计模式之策略模式_动力节点Java学院整理
- Java设计模式之迭代器模式_动力节点Java学院整理
- Java设计模式之解释器模式_动力节点Java学院整理