场景再现:
提供一个list外部只允许访问(例如一些配置文件或者properties),然后外部使用list
class A{ private static List<String> listTest; static { listTest = new ArrayList<>(); listTest.add("123"); } public static List<String> getListTest() { return listTest; } } class B { public static void main(String[] args) { List<String> listTest = A.getListTest(); System.out.println(listTest.size()); listTest.add("ddd"); List<String> listTest2 = A.getListTest(); System.out.println(listTest2.size()); } }
问题:
发现外部依然能够修改list。
理解list引用没有发生变化,只是list对象内容发生变化。那怎么限制外部无法修改list??难道只能深克隆吗
如果是这样的,是不是java对于引用类型变量,声名为private没有太大的意义
所以你要对外提供迭代器.而不是list.list本身就有修改自己的方法.所以你提供了list自然也就提供了修改list的功能.
我更多的是对引用类型变量声明为private意义的思考,,我声明为private,没有提供set方法,但是我还是能改变对象实际内容,,这个是不是说明声名称private没有太大的意义
@登顶:
1.你要想的是你要对外提供什么功能.
2.私有公有保护这些是用来实现你要提供的功能的.
3.不是简单的私有就外面改不了.
4.至于你说的引用类型外面也能改.那是因为这个类型对外提供了修改自己的能功能.如果你对外给一个没有set的类型只有get的类型的自然也就没法改.
5.你的误区在于第一条.本末倒置了.
@吴瑞祥: 功能需求:将配置文件加载到内存中,使用一个工具类,提供对配置文件信息的访问,希望不能进行修改。
@登顶: 那就对外提供一个get方法.传入配置名.返回配置字符串.
@吴瑞祥: 非常感谢!
然后我调整了一下代码
private static List<PropModel> propList = new ArrayList<>(); static { propList.add(new PropModel("1", "111")); } public static List<PropModel> getPropList() { List<PropModel> list = new ArrayList<>(); list.addAll(propList); return list; }
然后PropModel里边的set方法全部去掉了,只能通过构造方法修改值。
删除set是防止修改list中已有对象的值;然后修改对list的获取是防止对list的增删。
功能没问题,但是感觉好麻烦
@登顶: 这个是歧途..
正途是别用list了.因为你的需求list满足不了.自己写一个类型来提供你想要提供的功能.
ImmutableCollection