mutable immutable and final

昨天学习了有关java的mutable和immutable的知识,在这里,凭借着记忆,写一篇较短的blog。
一:什么是mutable和immutable:
 1. immutable指的是,一个变量在被分配了内存之后,他的值就不会被改变。例如:
int three = 3; 这句话的意思是指:在栈上开了一处内存,并将一个整数3放进了该处内存空间中,且该处内存空间的值在今后无法被修改。而mutable的变量则是相反,你可以在这个原本的内存中对数据进行修改,而不需要另外再开一处内存。
 2.那么three = 4, 这又是什么意思呢?其实就和我上面说的那样,他是另外在栈中开了一处内存,并将一个4放入其内。在java中,每个你声明的变量,他本身就只是一个地址,或者说是一个管理者,真正的数据则是被放在了该处地址指向的内存空间中。所以,你无法改变immutable变量的对应内存里的内容,你可以做的是让这个immutable去管理其他的内存,从而实现的值的改变。
 3.mutable的话就是指在一处管理的内存上进行修改。
二.对象的mutable和immutable:
 1.我们定义了一个对象,如果他的每个成员变量都是immutable的,且都无法被改变,那么我们就可以说这个对象是immutable的。我们来看如下的一份代码:
public class Message {
    private String name;
    private int ID;
    
    public Message(String name) {
        this.name = name;
        this.ID = name.hashCode();
    }
    
    public String getName() {
        return name;
    }
    
    public int getID() {
        return ID;
    }
}
view

分析一下这个类,我们发现除了在构造函数中队类的成员变量进行了一次初始化之后,成员对象就不会再被改变,因为通过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.

猜你喜欢

转载自www.cnblogs.com/-shuichi/p/10656504.html