static

那天我朋友问了我个问题,static和单例模式有什么区别,所以我觉得static可以讲一下

他的问题是,把对象弄成static是不是就不变了

显然,这是还没弄清楚引用和对象的区别

其实存放在静态区中的是引用,而不是对象。而对象是存放在堆中的。如果有这样一句话

public static final Book book = new Book();

意思就是book这个引用,指向了这个new出来的对象。

static的引用和正常的引用有什么区别?

当你加载了这个类的时候(第一次使用这个类的时候会加载这个类到jvm),这个static引用会率先被加载。所以,当我们第一次调用Book.book的时候,这个静态的book引用就会一直存放在静态区里了(当fullGC回收整个类才会销毁这个引用)。

而正常的引用,只能通过new出一个对象后才能使用,所以当对象被回收了,这个引用自然也回收了(而且非静态引用如果是方法中的引用,会存放在函数的栈里;如果是对象的引用,会和对象一起存放在heap里)。

final

final定义了之后,你就必须在一开始就需要赋值,所以上面那行代码就必须在一开始就赋值。而如果你想延迟加载,提高性能,那么就不可以用final。

单例模式

单例模式是如果实现的,就是通过调用这个类里的一个静态方法,弄一个if语句判断一下,如果有实例了,就返回这个实例,如果没有,就创建这个实例。其实并没有多大的技术含量。

第一种,最基本的思维。

public class Book {
private static Book book = new Book();
private Book() {}
public static Book getInstance() {
if (book == null) {
book = new Book();
}
return book;
}
}

这里为什么要判空呢?因为你这个是静态的,所以其他地方完全有Book.getInstance = null;的可能。

第二种,这里使用final,让引用的指向不可变,这样就不需要判空了

public class Book {
private static final Book book = new Book();
private Book() {}
public static Book getInstance() {
return book;
}
}

第三种,延迟加载(线程不安全,假如有多个同时发现是空的,会创建出好多实例)

public class Book {
private static Book book;
private Book() {}
public static Book getInstance() {
if (book == null) {
book = new Book();
}
return book;
}
}

第四种,添加线程安全功能,加一个关键字就可以

public class Book {
private static Book book;
private Book() {}
public static synchronized Book getInstance() {
if (book == null) {
book = new Book();
}
return book;
}
}

这个方法在多线程下的工作表现很出色

第五种,规避不需要的同步,因为上面的同步范围太大,有点浪费性能,在引用有指向的时候,是不需要同步的

public class Book {
private static Book book;
private Book() {}
public static synchronized Book getInstance() {
if (book == null) {
synchronized (Book.class) {
book = new Book();
}
}
return book;
}
}

第六种,静态内部类

public class Book {
private Book() {}
public static synchronized Book getInstance() {
return BookHolder.book;
}
private static class BookHolder {
private static final Book book = new Book();
}
}

第七种,枚举单例

public class Book {
private Book(){}
public static Book getInstance() {
return BookEnum.BOOK.getInstance();
} private static enum BookEnum {
BOOK;
private Book book;
private BookEnum() {
book = new Book();
}
public Book getInstance() {
return book;
}
}
}

最优,但是枚举这个东西可读性不高

单例模式(一)static、final和单例模式的更多相关文章

  1. JAVA Static方法与单例模式的理解

    近期用sonar測评代码质量的时候,发现一个问题,project中一些util类,曾经写的static方法都提示最好用单例的方式进行改正. 为此,我细致想了想,发现还是非常有道理的.这里谈谈我个人对s ...

  2. JDK设计模式之—单例模式和static关键字

    首先了解static 关键字 static声明的方法是静态方法,static声明的成员变量为静态成员变量.对于该类的所有对象来说,static的成员变量和static只有一份存储空间 即使没有创建该类 ...

  3. java——多线程——单例模式的static方法和非static方法是否是线程安全的?

    单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...

  4. [转]java static final 初始化

    http://tanbing1986411.blog.163.com/blog/static/7259798220103610224434/ java static final 初始化 1.stati ...

  5. java单例模式教程之java实现单例模式的8大方法

    单例模式是Java中常用的设计模式之一.单例模式属于创建型模式,它提供了一种创建对象的最佳方式. 单例模式只创建类的一个对象,之后在一定范围为可任意调用,确保只有单个对象被创建.这个类提供了一种访问其 ...

  6. DCL单例模式中的缺陷及单例模式的其他实现

    DCL:Double Check Lock ,意为双重检查锁.在单例模式中懒汉式中可以使用DCL来保证程序执行的效率. 1 public class SingletonDemo { 2 private ...

  7. Java 关键字static final使用总结

    Static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被 ...

  8. 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告

    编写实体类并且继承序列化接口时候,实体类会有警告,要生成一个静态的serialVersionUID. 上网搜了一下资料,现通俗解释一下: 点击前2个选项,会生成: private static fin ...

  9. 为什么构造器不能是abstract, static, final, native or synchronized的?

    Unlike methods, a constructor cannot be abstract, static, final, native  or synchronized. 1. A const ...

随机推荐

  1. uniapp上传图片转base64码

    uni.chooseImage({ count: 9, success: res => { this.imageList = this.imageList.concat(res.tempFile ...

  2. idea 2017 破解方法

    一.先进入Intellij IDEA的官网:https://www.jetbrains.com,下载安装 二.破解. 网上的破解方法较多,总结下来大概有下面几种办法供大家作为参考 声明:破解用于学习和 ...

  3. [HNOI2008][bzoj 1005]明明的烦恼(prufer序列)

    1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7121  Solved: 2816[Submit][Stat ...

  4. 分布式锁与实现--基于ZooKeeper实现

    引言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...

  5. 20175215 2018-2019-2 第十一周java课程学习总结

    第13章 Java网络编程 13.1 URL类 URL类是java.net包中的一个重要的类,URL的实例封装着一个统一资源定位符(Uniform Resource Locator),使用URL创建对 ...

  6. State Threads之网络架构库

    原文: State Threads for Internet Applications 介绍 State Threads is an application library which provide ...

  7. Python全栈开发第5天作业

    作业一:1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) 2) 将用户信息数据库文件和用户密码数据库文件纵向合并为一个文件/2.txt(追加) 3) 将/1.txt. ...

  8. OpenCV学习笔记(14)——轮廓的性质

    提取一些经常使用的对象特征 1.长宽比 边界矩形的宽高比                                       x,y,w,h = cv2.boundingRect(cnt) a ...

  9. Linux之tar命令

    命令格式: tar [-cxzjvf]   压缩打包文档的名称 欲打包目录 参数: -c :建立一个归档文件的参数指令 -x :解开一个归档文件的参数指令! -z :是否需要用 gzip 压缩? -j ...

  10. 数据解析框架之Gson

    GSON是由Google提供的,用于JAVA对象与JSON字符串之间互相转换的一个解决方案.用处很多,比如在前后台通讯中,前台先将java对象转化成JSON,然后将JSON传输给后台交由后台处理——相 ...