java静态变量是单例吗,单例模式和静态变量解决办法

单例模式和静态变量

看过很多对于单例模式的讨论,对于其中的一个问题,还是不太明白,希望牛人点明重点,醍醐灌顶。

比如说我要写一个类,来读取项目的配置文件。

可以有两种实现方法,

1,单例实现

import java.util.HashMap;

import java.util.Map;

/**

* 配置文件读取类的单例实现

*/

public class SinglePattern {

//静态私有对象

private static SinglePattern sp = new SinglePattern();

//配置文件的MAP

private Map configs;

/**

* 构造方法私有化

*/

private SinglePattern(){

//读取系统配置,放到配置文件的MAP里面去,这段代码省略...

configs = new HashMap();

}

/**

* 实例化方法

* @return 静态私有对象

*/

public static SinglePattern getInstance() {

return sp;

}

/**

* 读取配置文件

* @param key

* @return 配置信息

*/

public String getConfig(String key){

return configs.get(key);

}

}

2,静态实现

import java.util.HashMap;

import java.util.Map;

/**

* 配置文件读取类的静态实现

*/

public class StaticPattern {

//配置文件的MAP:设置成statci的变量,和单例一样,只有一份存在

private static Map configs;

/**

* 读取系统配置

*/

static{

//读取系统配置,放到配置文件的MAP里面去,这段代码省略...

configs = new HashMap();

}

/**

* 读取配置文件

* @param key

* @return 配置信息

*/

public static String getConfig(String key){

return configs.get(key);

}

}

这两种实现方法有什么不同吗,

很多项目采用的都是单例的实现,但是我感觉静态的实现更简单

望牛人点明

------解决方案--------------------

区别就是 第二种  可以改变 ,StaticPattern .configs =new   HashMap();

在工程的任何一个地方 ,都可以改变configs 使他指向另一个内存地址。

第一种 SinglePattern  是不能被改变的 ,但是你在单例的类中定义了 全局的变量存在线程安全问题 ,内部的configs 也是可以改变的。

若果你的变量configs 用final 修饰 就不会被改变了 , 效果就一样了。

java中的静态变量只会被加载一次。

------解决方案--------------------

SinglePattern :内存中 存在一个  SinglePattern 这样类型的实例,(实例的存在也是因为用到所以new一个对象出来,用不到的话,这个  实例就不用new ,内存占用“可控”)

StaticPattern : 没有实例(也可以有,new出来一个),直接用类名点方法调用

理论上 类 SinglePattern 是有可能被 GC的,就是说这块内存是有可能被回收的

但是 StaticPattern 占用的内存 则会被一直占用。

个人理解

------解决方案--------------------

单例是为了提供全局唯一的访问点&&同步问题,你第二种写法会出现同步问题。

------解决方案--------------------

1.单状态枚举是最优单例实现

2.单例模式是反模式

3.单例靠不住,创建第二实例的方法太多。。

------解决方案--------------------

http://www.360doc.com/content/13/1028/16/11253639_324825197.shtml

楼主可以看看

------解决方案--------------------

1、首先纠正个楼上的错误,楼主你的第二种写法并没有把Map暴露出去,所以外部无法将configs指向别的对象,final不需要加。

2、回答楼主的问题,主要说为什么建议使用单例而不是类的静态方法,楼主注意下你第二种方式的configs是static的,且初始化也是在static方法块中的,如果初始化过程步骤很复杂,如果再用到很多的成员变量参与初始化都需要设计成static的,且静态初始化的控制权是在Java手上的,这么做可能导致混乱。

其实如果只是简单的映射配置文件,的确方法1、方法2都可行。

------解决方案--------------------

单例不在于怎么实现,在于怎么用。

大部分人都把单例用成了静态,那就跟静态区别不大。

设计模式本来就是给一些表面的东西起名字,没必要纠结这些概念。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值