首先了解static 关键字

static声明的方法是静态方法,static声明的成员变量为静态成员变量。对于该类的所有对象来说,static的成员变量和static只有一份存储空间

即使没有创建该类的对象(实列),也可以使用该类static的成员变量和static方法。

  static所修饰的成员变量和静态代码块 当虚拟机对该类初始化的时候就会被创建,也就是 即使没有创建这个类的实列,java虚拟机也能根据类名在运行时数据区的方法内找到他们。(也就是说类的初始化和创建类的实列并不是一回事)

静态方法中不能使用this关键字

  这个也很好理解。当一个对象创建好之后,java虚拟机就会给它分配一个引用自身的指针:this。也就是说 this是当前对象的引用。红字部分说了 是当前对象的引用,而执行static方法的时候 对象的实列可能还没被创建,所static方法中不能引用this关键字。同理 不止是this关键字,static方法中 不可访问任何非static的成员变量。同理 非static的成员变量 在类被初始化的时候才会被创建

为什么作为程序入口的main方法是static方法

  把main()方法定义成static的静态方法,java虚拟机只要加载了main方法所属的类,就能执行main方法。而无需先创建这个类的实列

试想:如果main方法不是static的时候 运行main方法需要创建该类的实列,类的main是创建实列的入口。

补充:不管是静态方法,还是普通方法 他的字节码都位于方法区内。

为什么 static 成员变量 要和final一起用 public static final int xxx ;

  因为static关键字修饰的成员变量,程序中只有一份。多个线程同时操作的时候 会产生并发的bug。final关键字 修饰的变量不能被更改

  所以static final连用 可以防止静态变量 并发的bug。

  static 也可有ThreadLocal连用 同样可以防止线程并发的bug

利用static关键字 实现单例模式(懒汉式)

  在程序启动或单件模式类被加载的时候,单件模式实例就已经被创建。

  2.1:类的构造函数定义为private的,保证其他类不能实例化此类,

  2.2:然后提供了一个静态实例static XX  xx= new XX()并返回给调用者。

  它的好处是只在类初始化的时候创建一次实例,不会存在多个线程创建多个实例的情况,避免了多线程同步的问题。

  缺点也很明显,即使这个单例没有用到也会被创建,而且在类加载之后就被创建,内存就被浪费了。

public class Singleton{
//类被搜索加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。
private static Singleton instance = new Singleton();//static的属性,是在类定义被JVM所加载时 就初始化完毕的,是类的所有实例共有的
private Singleton(){//私有的构造方法 }
public static Singleton getInstance(){
return instance;
}
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);
}
}

以下补充类的初始化过程,了解一下 类的初始化和创建类的实列区别

饿汉式单例模式

当程序第一次访问单件模式实例时才进行创建。

public class Singleton{
private static Singleton instance ;
private Singleton(){ }
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);
} }

注意synchronized关键字的使用,防止因为并发导致创建多个对象

反序列化打破单例模式

反序列化会创建一个对象,打破了单例只有一个实列的约定。

public class Singleton implements Serializable{
private static final long serialVersionUID = 1L; private static Singleton instance ;
private Singleton(){ }
public static synchronized Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
} public static void main(String[] args) throws Exception {
Singleton s1 = Singleton.getInstance(); ByteArrayOutputStream buf = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(buf);
o.writeObject(s1); ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(buf.toByteArray()));
Singleton s2 = (Singleton) in.readObject();
System.out.println(s1==s2); } }

解决办法: 在类中增加readResolve()方法

private Object readResolve(){
return instance;
}

如果一个类提供了readResolve()方法,重新指定反序列化的对象。

那么在执行反序列化操作时,先按照默认的方式或者用户自定义的方式进行反序列化,最后调用readResolve()方法,该方法返回的对象为反序列化的最终结果。

JDK设计模式之—单例模式和static关键字的更多相关文章

  1. 关于JDK中采用单例模式的类

    JDK设计模式应用——单例模式(Singleton) <JDK源码分析>的分支,讲解设计模式在jdk中使用. 我们从三个方面讲述,一是:jdk源码中的设计模式:二是:讲解设计模式(UML图 ...

  2. Java 静态static关键字,main函数,对象的初始化过程,对象调用成员,单例模式的设计,静态代码块(6)

    Java 静态static关键字,静态代码块详情参考:static的使用原理讲解http://www.cnblogs.com/itcqx/p/5519464.html main函数: java Mai ...

  3. 零基础学习java------day8------javabean编写规范,继承,static关键字,代码块,单例设计模式

    0. 今日内容提要 1. javabean书写规范 javabean:一个普通的类,用来描述事物的类,里面不包含任何的业务逻辑,只是用来存储数据. 比如:Teacher,Student,Mobile. ...

  4. 再议Java中的static关键字

    再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...

  5. 【设计模式】单例模式-Singleton

    [设计模式]单例模式-SingletonEnsure a class has only one instance, and provide a global point to access of it ...

  6. GJM : C#设计模式(1)——单例模式

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  7. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  8. 每天一个设计模式-4 单例模式(Singleton)

    每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...

  9. 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则

    加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...

随机推荐

  1. mysql启动服务

    mysql.server start 启动mysql服务mysql.server stop 停止mysql服务 mysql密码:123456Az_

  2. docker 删除所有退出的容器

    方法一: #显示所有的容器,过滤出Exited状态的容器,取出这些容器的ID, sudo docker ps -a|grep Exited|awk '{print $1}' #查询所有的容器,过滤出E ...

  3. MSSQL死锁进程查看及关闭

    select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran ...

  4. jquery.validate 远程验证remote使用详解

    目的: 试了一下远程验证,试了好几次,得出小结,可以记录下,提醒以防绕路. ----------------直接贴图,省事明了---------------- 1.引用js 2.demo的html & ...

  5. Oracle通过SCN做增量备份修复DG

    DG由于网络原因或者bug原因经常不同步,有时隔得时间久了,就会丢失归档日志,或者长时间的归档恢复较慢,有一种可以基于scn的方式来恢复DG库,使用基于scn的增量备份来恢复standby库可以节省大 ...

  6. JSP 页面跳转的实现方法

    客户端跳转 1. 使用 href 超链接标记  <a href="new.jsp">跳转</a> 2. 使用表单提交完成跳转  <form actio ...

  7. db2数据库备份及恢复

    导出 1. 连接数据库,命令如下: db2 connect to db_name user user_name using password db_name 是指数据库的名字, user_name 是 ...

  8. vue项目中跳转到外部链接方法

    当我们在文件中,如果是vue页面中的内部跳转,可以用this.$router.push()实现,但是如果我们还用这种方法跳到外部链接,就会报错,我们一看链接的路径,原来是我们的外部链接前面加上了htt ...

  9. 六、pyqt5对话框——QInputDialog、QColorDialog、QFontDialog、QMessageBox、QFileDialog

    目录:  一.对话框综合示例 二.QDialog 三.QInputDialog 四.QMessageDialog 五.QFileDialog pyqt5的对话框有多种类型,比如输入对话框(QInput ...

  10. 【转】async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...