分析一下这个类,我们发现除了在构造函数中队类的成员变量进行了一次初始化之后,成员对象就不会再被改变,因为通过observer返回的是immutable的变量,客户端无法直接对该内存的数值进行修改,我们的代码是安全的。
public class Person { private String firstname; private String lastname; private Date time; public Person(String firstname, String lastname, Date time) { this.firstname = firstname; this.lastname = lastname; this.time = time; } public String getFirstname() { return firstname; } public String getLastname() { return lastname; } public Date getTime() { return time; } } View Code这是一个很经典的例子,这里的成员变量有两个是immutable的还有一个Date类的对象是mutable的,这样我们的代码就是一个mutable的了,有了漏洞。当我们进行如下操作:
Instant now = Instant.now(); Person jim = new Person("Jim", "Smith", new Date(now.toEpochMilli())); System.out.println(jim.getTime()); Date danger = jim.getTime(); danger.setTime(now.toEpochMilli() + 3600000); System.out.println(jim.getTime()); View Code 这里我们实现建立了一个person类的对象,并用当前时刻的EpochMilli直取初始化这个Date,当我们Date类型的成员变量调用observer存入到danger中,对danger进行一个set操作时,我们发现,原对象的time成员变量中的内容被修改了。这就是mutable,我们也可以从中看出它的危害是巨大的。 mutable允许外界直接对当前返回回来的地址内的内容进行操作,危害极大,而immutable则禁止。 三.final: 最后我们来区分一下final和immutable。从之前的介绍中我们得知了,immutable的变量的只能修改他管理的地址,而地址对应的内容无法修改。那么final是干什么的呢?其实很简单,被定义了final的变量,无法指向一个新的地址,他只能从一而终的对一处地址进行访问,如果是immutable的,那么他既然无法指向其他的地址,那么就无法指向其他的值。所以,final是对管理者的限制。 举个例子: final List<String> people = new ArrayList<>();对于上述的这么一个声明,由于List是mutable的,我们可以对他进行add,remove, sort…等等的操作,但是加了final之后,他就与一处内存绑定上了,这个时候,如果有以下的操作:people = new ArrayList<>();那么直接就会被静态类型检查报出error.
转载于:https://www.cnblogs.com/-shuichi/p/10656504.html
相关资源:JAVA上百实例源码以及开源项目