单例模式(一)static、final和单例模式
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和单例模式的更多相关文章
- JAVA Static方法与单例模式的理解
近期用sonar測评代码质量的时候,发现一个问题,project中一些util类,曾经写的static方法都提示最好用单例的方式进行改正. 为此,我细致想了想,发现还是非常有道理的.这里谈谈我个人对s ...
- JDK设计模式之—单例模式和static关键字
首先了解static 关键字 static声明的方法是静态方法,static声明的成员变量为静态成员变量.对于该类的所有对象来说,static的成员变量和static只有一份存储空间 即使没有创建该类 ...
- java——多线程——单例模式的static方法和非static方法是否是线程安全的?
单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...
- [转]java static final 初始化
http://tanbing1986411.blog.163.com/blog/static/7259798220103610224434/ java static final 初始化 1.stati ...
- java单例模式教程之java实现单例模式的8大方法
单例模式是Java中常用的设计模式之一.单例模式属于创建型模式,它提供了一种创建对象的最佳方式. 单例模式只创建类的一个对象,之后在一定范围为可任意调用,确保只有单个对象被创建.这个类提供了一种访问其 ...
- DCL单例模式中的缺陷及单例模式的其他实现
DCL:Double Check Lock ,意为双重检查锁.在单例模式中懒汉式中可以使用DCL来保证程序执行的效率. 1 public class SingletonDemo { 2 private ...
- Java 关键字static final使用总结
Static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被 ...
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
编写实体类并且继承序列化接口时候,实体类会有警告,要生成一个静态的serialVersionUID. 上网搜了一下资料,现通俗解释一下: 点击前2个选项,会生成: private static fin ...
- 为什么构造器不能是abstract, static, final, native or synchronized的?
Unlike methods, a constructor cannot be abstract, static, final, native or synchronized. 1. A const ...
随机推荐
- Lyft 基于 Flink 的大规模准实时数据分析平台(附FFA大会视频)
摘要:如何基于 Flink 搭建大规模准实时数据分析平台?在 Flink Forward Asia 2019 上,来自 Lyft 公司实时数据平台的徐赢博士和计算数据平台的高立博士分享了 Lyft 基 ...
- EL表达式接收值
- ListView如何获取点击单元格内容
Point m_MBRpt = listView1.PointToClient(Control.MousePosition); ListViewItem lstrow = lis ...
- JVM(七),JVM面试小知识
七.JVM面试小知识 1.JVM三大性能调优参数 -Xms -Xmx -Xss 的含义 2.java内存模型中堆和栈的区别 3.不同JDK版本中的intern()方法的区别
- docker 卸载与安装
卸载 Docker自17.03版本开始分为两个版本Docker CE和Docker EE: Docker CE:Docker Community Edition,即Docker社区版 Docker E ...
- Visualizing and Understanding Convolutional Networks
前言:研究卷积神经网络,把阅读到的一些文献经典的部分翻译一下,写成博客,代码后续给出,不足之处还请大家指出. 本文来自:tony-tan.com Github:github.com/Tony-Tan ...
- python3网络编程
网络编程(定义) 网络编程的本质就是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机,数据传递本身 没有多大难度,不就是把一个设备中的数据发送给一个设备,然后接收另一个设备的反馈的数据. ...
- [CSP-S模拟测试]:B(DP+数学)
题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...
- 基于libcurl的restfull接口 post posts get gets
头文件 #pragma once #ifndef __HTTP_CURL_H__ #define __HTTP_CURL_H__ #include <string> #include &q ...
- unity的Tilemap学习笔记
1,如果要实现当tilemap里面的格子与其他的对象发生碰撞后,消除碰撞的那个格子,使用如下代码. void OnCollisionEnter2D(Collision2D collision) { V ...