单例模式(一)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 ...
随机推荐
- MongoDB——增删改查
文档结构: { "_id": ObjectId("5d5e5de597eb2f0b70005d1a"), , "word_records": ...
- JavaScript复制内容到剪贴板
移动端 需要复制内容到剪贴板时, clipborad.js 不支持ios微信版浏览器,可配合使用 execCommand 使其兼容, 完成一键复制淘口令的功能. 注意使用clipborad.js时,i ...
- 交换机配置——三层交换机实现VLAN间通信
一.实验目的::用三层交换机让同一vlan的主机能通信,不同vlan的主机也能通信 二.拓扑图如下 三.具体步骤如下:. 先给每台主机和服务器配置ip地址和网关 例: (1)S1三层交换机配置: Sw ...
- CentOS8编译openocd-0.10.0
1.sudo yum install libusbx-devel 2. ./configure --prefix=$HOME/openocd-0.10.0 --enable-jlink CFLAGS= ...
- mysql5.7提示密码过期的解决方法
首先把MySQL关闭 打开一个终端,输入 sudo /usr/local/mysql/bin/mysqld_safe --skip-grant-tables 执行完命令后,再打开一个新的终端 sudo ...
- PHP-windows下安装
下载 Apache下载地址:http://httpd.apache.org/download.cgi PHP下载地址:http://php.net/downloads.php 解压 解压到安装路径下H ...
- Apache Ranger && HDFS
Apache Ranger && HDFS 标签(空格分隔): Hadoop HDFS HDFS对于任何Hadoop大数据平台来说都是核心组成部分,为了加强对Hadoop平台的数据保护 ...
- Hive使用与安装步骤
1.Hive安装与配置 Hive官网:https://hive.apache.org/ 1. 安装文件下载 从Apache官网下载安装文件 http://mirror.bit.edu.cn/apach ...
- 「CSA Round #41」BFS-DFS
题目链接 戳我 \(Description\) 给出一个图的\(bfs\)序和\(dfs\)序,构造出一个满足条件的图,边的扫描顺序为读入顺序 \(Solution\) 这个题还是很简单的. 先来看看 ...
- python3笔记二十四:Mysql数据库操作命令
一:学习内容 Mysql操作命令:启动服务.停止服务.连接数据库.退出数据库.查看版本.显示当前时间.远程连接 数据库操作命令:创建数据库.删除数据库.切换数据库.查看当前选择的数据库 表操作命令:查 ...