=操作符与值/引用类型的理解 2020-06-23 18:19 ```java int x = 1; User u = new User(); ``` 如果突然让我看这两句代码,并让我解释,我一定会说”定义一个int类型的变量x,把1赋给x;定义一个User类型的变量u,然后在堆区开辟(申请,创建)一块内存空间存放User(),接着将内存空间的地址值赋给u“。 但是仔细想想,同样是赋值符号 =,为什么一个是赋值(内存空间中存的值),一个是赋地址值(内存空间的地址)呢? 原来我忽略了一个地方,new是一个”函数“,它创建内存空间,并返回所创建内存空间的地址值。所以是new把地址值返回了,被返回的这个东西作为值赋给了u。所以也是赋值。 以前画过类似的图,其实都是不大正确的,这种图能表现出赋值结果的情况,但是错误的展示了赋值符号的执行情况。【因为按照下图来看,一个是将内存空间中的值赋给变量,另一个是将内存空间的地址值赋给变量】 ![](/image/cb000585-9671-45a5-8117-c890e0f03dec.jpg) 所以赋值符号 = ,在任何情况下都只是赋”值“。**它只负责把右操作数对应的内存空间中储存的东西拿出来,放在左操作数对应的内存空间中。**无论操作数是值类型,还是引用类型。 值类型和引用类型在表现上的不同,不是因为赋值符号 = 引起的。而是因为变量内部储存的东西引起的。 要了解值类型和引用类型,首先要知道值类型和引用类型本身是名词,说的是不同的类型;接着他们也是形容词,是用来形容某种 数据类型 是什么类型的。所以你可以像这样说:int数据类型是值类型,String数据类型是引用类型。 值类型储存的是基本的值,这些值是常量,储存在内存中的常量区,由于是常量,所以是不可变的,这就导致了它的一些特性。 比如 ```java int x = 1; int y = x; x = 2; printf("%d",y); ``` 以上代码逻辑无论换做任何语言,最后输出y的值均为1。其根本原因有两个: 1、赋值 = 符号的特性(上面说的) 2、常量是不可变的 接下来我们分开解析上面的代码来说明为什么上述两个原因导致了最后输出为1. `int x = 1`,将常量区的某块储存着1的内存空间的值赋给x(将1赋给x) `int y = x`,将变量x所在的内存空间中的值赋给y(将1赋给y),由于赋值符号 = 的特性,所以这里只是把x中储存的值1赋给了y所在的内存空间,所以y表现出来也是1 `x = 2`,将常量区的某块储存着2的内存空间的值赋给x(将2赋给x),由于常量是不可变的,所以不能把原来1所在内存空间中储存的1修改为2。必须重新找储存着2的内存空间,将值赋给x。 由于以上原因,这样对x的修改就不会影响到y了。即使曾经执行过 y = x的操作。 引用类型储存的是组合的值,这些值由不同的内存空间储存,这些内存空间各自独立,排列在一起作为一个整体展现给外界,外界只看到整个整体的储存空间。类似下面这样。引用类型其实是相当于利用一个中间盒子,将多个值类型组合在一起,装在盒子里,由于有了盒子的存在,所以就会有另外的一些特性。 比如 ```java User u1 = new User(18, "hanxu"); User u2 = u1; System.out.println(u2); //User{age=18, name='hanxu'} u1.setAge(20); System.out.println(u2); //User{age=20, name='hanxu'} ``` 以上代码逻辑换做任何语言,输出都相同(C语言中的struct关键字情况不一样是因为struct结构体是值类型,此处的前提是**类Class**)。其根本原因有三个: 1、赋值 = 符号的特性(上面说的) 2、常量是不可变的 3、中间人User类型的存在 仍然是上述分析步骤,不过由于User类型的存在,它像一个袋子一样,将`int age`和`String name`装起来,无论袋子里的东西是值类型还是引用类型,对外界是不可见的,对外界来说只是拿着这个袋子,袋子里面装的东西修改,但是袋子本身并不会修改。所以所有拿到相同袋子的人(u1和u2)发生的变化都会同步。 ![](/image/01608a7a-cf19-42e6-9a33-85b05fab501f.jpg) 值类型就相当于一包未开封的薯条,现在我拿着一包薯条,突然不想吃了,想换一包虾条,那么只有把整个薯条都拿走,再拿来一包虾条,对我来说我手里是从拿着薯条到换成了虾条,拿的东西发生了根本的改变。 引用类型就相当于一个大的购物袋,里面放着薯条,虾条,果冻,牛奶。我现在想换掉其中的果冻,换成了干吃面,那么对我来说,里面的东西虽然已经不一样了。但我还是拿着包装袋。(这个比喻有助于理解它们的区别,但是不能说明发生的现象,我实在想不出其他比喻了。要理解现象的原因请还是仔细阅读上述解释文字。) --END--
发表评论