interView - 静态类与单例

来源:互联网 发布:linux查看ls命令手册页 编辑:程序博客网 时间:2024/05/24 04:29

既然单例里有个静态实例对象,为什么不直接使用静态类?静态变量是在内存常驻的么?GC会不会销毁?多线程访问单例的安全问题?


1.静态类(一个类,所有方法为静态方法)比单例具有更好的性能,因为静态方法在编译期绑定。

编译期绑定称为静态绑定,在java中只有private,final,static和构造方法是静态绑定,动态绑定在运行时根据具体的对象的类型来绑定。

在方法的第一次加载时,无论静态方法和非静态方法,虽然都已经在Method Table中分配了,但非静态方法在分配时,会考虑到他的父类,一直到Object为止,

也会把父类的方法和字段都分配,所以非静态方法在分配上,有个向上查找的过程,比静态方法要复杂的多,但第一次载入后他们就没有差异了。

2.override的区别,静态方法是不能被覆盖的,这样就导致其没有太多的灵活性,另一方面可以通过继承的方式覆盖单例类中定义的方法,就是说单例更能

面向对象,提供不同的实现。

3.如果是一个非常重的对象。单例可以延迟加载,但静态类没有这样的优势,它始终保持着被热切加载的状态。

4.对于维护状态信息,单例则比静态类更适合,因为静态类中静态方法只能使用静态变量,比较容易产生bug。


静态变量是随着类的加载而加载,静态变量一旦被加载到内存,在这个类被卸载之前,它就一直存在,而类通常是在应用程序结束时才会被卸载,

所以说静态变量是内存常驻。GC不会被销毁。

什么是类的加载,类什么时候被加载呢,当程序主动使用到某个类时,如果该类还未被加载到内存中,系统会通过加载,连接,初始化三个步骤

对类进行初始化,JVM会连续完成这三个步骤,也把这三个步骤称为类加载或类初始化。


懒汉式的单例可通过sychronized同步方法解决,饿汉式可通过双重校验琐来解决,就是将单例对象声明为volatile类型,通过两次判断对象是否为空以及使用同步方法块

来解决线程的安全问题.代码如下:

  1. public class Singleton {  
  2.     private volatile static Singleton singleton;  
  3.     private Singleton (){}  
  4.     public static Singleton getSingleton() {  
  5.     if (singleton == null) {  
  6.         synchronized (Singleton.class) {  
  7.         if (singleton == null) {  
  8.             singleton = new Singleton();  
  9.         }  
  10.         }  
  11.     }  
  12.     return singleton;  
  13.     }  
  14. }  



0 0
原创粉丝点击