java的设计模式

java 面试中单例模式基本都是必考的,都有最推荐的方式,也不知道问来干嘛。下面记录一下

public class singleton {
 private static final singleton instance = new singleton;
 private singleton{}
 public static singleton getinstance{
 return instance;
}

其实真心觉得没什么问题

但面试的时候,你不能这样回答,面试官不开心的,你要回答

public class singleton {
 private volatile static singleton instance; //声明成 volatile
 private singleton {}
 public static singleton getsingleton {
 if  { 
 synchronized  {
 if  { 
 instance = new singleton;
 return instance;
}

你看加个延迟加载

麻烦!!!
但也有应用场景的,在资源占用很多,又不常用的情况下,可以考虑用懒汉模式


public class singleton {
 private final static class singleholder {
 private static final singleton instance = new singleton;
 private singleton {
 public static singleton getinstance {
 return singleholder.instance;
}

因为这个是 jvm 保证其线性安全性的,而且会在加载的时候创建,又不依赖版本,所以以前会比较推荐。

其实上面的东东都有致命的危险!反射
上面按正常人类的做法是不会产生多个实例,如果会产生多个实例是说明上面的方式或多或少不够完美 ,比如反射


@test
public void test throws classnotfoundexception, illegalacces___ception, instantiationexception, nosuchmethodexception, invocationtargetexception {
 constructor ? cls = singleton.class.getdeclaredconstructor;
 cls.setaccessible;
 singleton singleton =  cls.newinstance;
 assertnotequals);//明显这两个对象是不一样的!!!
}

也就是说上面的方式面对复杂的序列化或者反射攻击,可能会出现问题!
比如:


@test
public void test throws classnotfoundexception, ioexception {
 //序列化对象到文件
 objectoutputstream objectoutputstream = new objectoutputstream);
 objectoutputstream.writeobject);
 //从文件中读取对象
 file file = new file;
 objectinputstream objectinputstream = new objectinputstream);
 singleton singleton =  objectinputstream.readobject;
 //判断是否是同一个对象
 assertnotequals);
}

当然也有应对序列化的方式。
就是在类中添加readresolve函数,因为反序列化中,如果存在这个函数,序列化的结果就是这函数的值。
所以你在要序列化中的类添加这句就可以了。



private object readresolve {
 return getinstance;
}

但面对反射就确实无力了。

public enum singletonenum {
 instance;
}

以上

Copyright © 2018 百家乐试玩百家乐试玩-百家乐游戏 All Rights Reserved