[JAVA]如何定义好一个静态final域
来源:互联网 发布:清华大学c语言教材 编辑:程序博客网 时间:2024/06/14 20:00
背景描述:
最近在做一些JAVA方面的开发,时常需要定义一些常量,比如String类,Map类等等。
public static final String ADDRESS = "CSDN";
上述的定义很常见,但是对于如何定义一个常量的map,看了公司一些同事的做法如下:
public class Constants{public static final Map<String,String> ADDRESS_MAP=new HashMap<>();static{ ADDRESS_MAP.put("1","CSDN"); ADDRESS_MAP.put("2","CNBLOGS");}}
其实这种做法是及其不安全的,读者有兴趣的可以尝试下,在外部调用:
public static void main(String[] args) { Constants.ADDRESS_MAP.put("1","333"); System.out.println(Constants.ADDRESS_MAP); }
很不幸,我们的值被改变了。
今天抽了半个小时的时间,学习了下,特总结之。
首先先介绍2个概念,不可变对象和可变对象。从别人博客上找来了一个这个的定义。引用自CSDN博客,可点击访问。
可变类和不可变类(Mutable and Immutable Objects)的初步定义:
可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容。
不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。
Map、List都是可变对象,因此我们将其定义成final域并没有实际的效果。
下面提供2种做法:(参考自effective java第13条)
Method 1:
public static final Map<String,String> MAP = Collections.unmodifiableMap(new HashMap<String,String>() { private static final long serialVersionUID = 1338447211708407707L; { put("1","2"); } } );
这个时候再想改变其值,就是不可能的了,当然这个时候的final修饰符也没什么意义了。
Method 2:
使用clone方法。将可变对象定义成private类型的,并且提供一个静态方法去获得这个对象的clone返回值。
当Map的value是不可变对象的时候,这个方法的确是可以的,但是当value是一个可变对象的时候,我们发现,这种方法并不有效。如下例子(这里的对象就不给出啦,很简单的一个对象)。
private static final HashMap<String,Book> ADDRESS_MAP=new HashMap<>();static{ ADDRESS_MAP.put("1",new Book("sss","qqq")); ADDRESS_MAP.put("2",new Book("qqqxx","mmmxx"));}public static Map<String,Book> get_address_map(){ return (Map<String, Book>) ADDRESS_MAP.clone();}
note:但是本人不建议使用方法2,因为clone如果是浅拷贝则依旧会产生问题,这个时候外界一样可以对其进行修改。
综上,我更推荐使用第一种方式!
- [JAVA]如何定义好一个静态final域
- Java 如何 定义 静态 map
- java中的关键字static(静态变量)和final定义常量
- java原样输出一个定义好数组
- java开发定义一个好的变量名
- Java 工程师如何得到一个好 Offer
- java中如何定义一个二维数组
- Java如何定义一个二维数组
- Java静态的定义
- java初学 终态类final定义区别
- java 中的常量定义,final 的问题
- 7.java final 常量的定义
- java 中定义的final常量
- JAVA中关于静态static和final
- 修改java的静态final变量
- 如何定义一个类别
- android开发(如何开发一个可以维护的好项目):一 、定义基类
- 作为一个Java编程新手该如何学习好…
- tyvj 1933 关于 复杂度 的教训~
- 解决javaWEB中前台传数据到后台中文乱码问题的3种方法
- URAL 1416 Confidential <最小生成数和次小生成数>
- swift6-元祖
- 内部类里的常规内部类
- [JAVA]如何定义好一个静态final域
- 反汇编代码里的地址 链接地址 运行地址 存储地址位置无关码 位置有关码
- Android初级教程XUtils实现“断点续传”下载
- 简单的坦克大战模拟小游戏
- appium:Could not detect Mac OS X version
- Spring AOP 代理模式
- 工作一年
- 【DRP】-用户登录-session和重定向
- wordpress 文章的插入,修改,读取,删除