final、static、和单例模式
设计模式主题写了一篇单例模式以后,有朋友建议,写下final 和单例的关系,于是准备顺便写下final、static。
final
final、意为最终的。final修饰的变量在定义之后必须立即赋值,不能被修改。
单例模式中经典的懒汉式,就是采用延迟加载,提高性能,那这个时候就不能用final修饰。
static
首先、static 意为静态的、static修饰属性、对象,强调只有一个,位于静态区。
static的保证唯一性,指的是static修饰的静态成员变量是唯一的,多实例共享唯一成员。
public static final Cat cat = new Cat();
上面的代码,是我们常见的写法,但很多人对次误解:
- 放在静态区中的是引用,而不是对象。对象被new 出来后存放在堆内存中对。
- cat 是一个引用,它指向了new出来的对象,这个对象在堆内存中。
- 被final 修饰的对象必须立即赋值且不能再改变。
- cat 被定义后立即被赋值,指向new的Cat实例。
static引用和普通引用有什么区别?
当程序加载这个类的时候(第一次使用时,被加载到jvm),static修饰的引用会率先被加载、一直存放在静态区里,直到fullGC回收整个类时才会被销毁。
普通引用:只能通过new一个对象后才能使用,当对象被回收,引用也会被回收
** 注:非静态引用,如果是方法引用,会存在函数栈里,随方法出栈而销毁,如果是对象,会和对象一起存在堆里,即:静态资源可以被多次使用。 **
单例模式
通过私有构造函数、提供提供全局访问点,使得一个类Class只有唯一实例存在。达到节省资源,提高应该性能的目的。
单例模式中,经典的懒汉式、饿汉式,经典阐释了static、final 的用法。
单例模式的详细内容,点这里查看。
懒汉式
public class Singleton {
//定义一个静态变量存储当前类的对象
private static Singleton uniqueInstance = null;
//私有化构造方法
private Singleton(){}
//定义一个静态方法返回类的对象
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
饿汉式
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return uniqueInstance ;
}
}
final、static、和单例模式的关系?
public static final Cat cat = new Cat();
1. 如果有人非要问他们之间的关系,抱歉,个人认为,没有关系。
只因他们所各有的特质,搭配起来使用,效果倍棒。
2. final 修饰变量不可修改,有人可能会误解说,这不就是单例了么?
不是的,final 修饰的这个变量本身是不能被改变的。像示例中的cat.
但,这不妨碍我可以继续new 出更多个Cat实例。所以final的,并不是一定是单例的。