Java中单例模式和静态类的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中单例模式和静态类的区别相关的知识,希望对你有一定的参考价值。

单例模式:

在框架中通过反射机制在程序运行时由框架生成一个类的实例,该实例是由框架负责维护;当然我们自己也可以实例化这个类,此时我们自己实例化的对象和框架维护的实例是互不影响的;

类的实例对象是由引用指向堆中保存的,单例是由框架中的引用指向堆中的一个实例,而我们自己创建的对象是另一个指向堆中的实例两个互不干扰;但是在使用起来,我们在不同地方改变单例全局的单例都变了,看起来好像静态一样但是实际上我们使用的只不过都是框架维护的一个实例而已;

举例:

@Component
public class Person
    private String name;
    Private Integer age;
    //get set 方法...省略不想写;

在框架启动时,我们就获得了一个Person类的实例,这个实例由框架内部一个引用指向,在程序使用时我们只需把地址赋于需要的地方,也就是说实际上大家用的都是一个对象;

就在这时,我们自己开心的new 了一个Person对象;此时我们通过set方法改变该对象不影响其他指向单例对象的变量;


静态类:

首先java中的静态类指的大多数是内部类;作为一个成员变量它静态才有意义,此时无论程序中的任何部分调用了该静态类的外部类,并通过方法改变了内部类的数据;此时该程序中的所有该内部类的实例都改变了,互相影响;因为静态变量是存储在方法区内的,而且就一份,无论谁使用该静态变量都是去方法区查询该对象的状态,所以互相干扰;

参考技术A 找到知乎一个很好的答案:
两者占内存不一样吧。
没记错的话,类加载的时候都要加载类的定义;执行方法的时候都要占用栈;但是单例需要在堆里面new一个内存空间出来,静态方法ms不用。

我的习惯用法是不需要依赖于其它类或资源时,用静态方法,这时就是一个面向过程的函数而已;如果需要依赖其它类的实例,或者需要某些资源时,用单例。

java中3中单例模式例子

java面试官也经常面试这个单例模式,一般能说出两私一公就不错了

java程序员平时开发用的少,但面试遇到多啊,也是有必要研究下的

什么叫两私一公

  1. 私有的构造函数
  2. 私有静态实例属性
  3. 公共的获取实例的静态方法

基础知识点

多线程、线程安全、static、构造函数、枚举

例子1

传统单线程环境下

缺点:线程不安全

技术图片

 

例子2

  • 多线程下通过synchronized保证线程安全
  • 跟例子1就多了同步,实例初始过了就直接返回实例不用进入同步代码块了
  • 多重检查锁的方式去保证安全
  • 缺点:还是可以通过反射去创建实例,不完美啊
技术图片

 

例子3(完美)

利用枚举的特性在JVM层保证绝对的单例

技术图片

 

为啥枚举的单例就完美了?

枚举本身是无法通过反射、克隆、反序列化等等把对象初始出来的。

枚举底层原理我就不在这里细说了。

总结

  • 搞懂两私一公(面试的时候能说出第2个例子就可以)
  • 枚举完美单例(能说出第3个例子就非常好)

以上是关于Java中单例模式和静态类的区别的主要内容,如果未能解决你的问题,请参考以下文章

java中3中单例模式例子

java 类中静态变量 和 单例模式下对象中的成员变量 有啥区别?使用场景是啥?

Android中单例模式和静态方法在效率上哪个好

Java单例模式详解

请问java 单例类 与 静态类 有何不同?

单例模式 静态库和动态库的区别