我是靠谱客的博主 怕孤单白开水,这篇文章主要介绍面试必考-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和单例模式的全部内容,更多相关面试必考-static、final和单例模式内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部