1.2 赋值
1.2 赋值
声明变量之后,就在内存分配了一块位置,但这个位置的内容是未知的,赋值就是把这块位置的内容设为一个确定的值。Java中基本类型、数组、对象的赋值有明显不同,本节介绍基本类型和数组的赋值,对象的赋值第3章再介绍。
1.2.1 基本类型
(1)整数类型
整数类型有byte、short、int和long,分别占1、2、4、8个字节,取值范围如表1-1所示。
我们用^表示指数,2^7即2的7次方。这个范围我们不需要记得那么清楚,有个大概范围认识就可以了。第2章会从二进制的角度进一步分析表示范围为什么会是这样的。
赋值形式很简单,直接把熟悉的数字常量形式赋值给变量即可,对应的内存空间的值就从未知变成了确定的常量。但常量不能超过对应类型的表示范围。例如:
1 | byte b = 23; |
但是,在给long类型赋值时,如果常量超过了int的表示范围,需要在常量后面加大写或小写字母L,即L或l,例如:
1 | long a = 3232343433L; |
之所以需要加L或l,是因为数字常量默认为是int类型。
(2)小数类型
小数类型有float和double,占用的内存空间分别是4和8字节,有不同的取值范围和精度,double表示的范围更大,精度更高,具体如表1-2所示。
取值范围看上去很奇怪,一般也不需要记住,有个大概印象就可以了。E表示以10为底的指数,E后面的+号和-号代表正指数和负指数,例如:1.4E-45表示1.4乘以10的-45次方。第2章会进一步分析小数的二进制表示。
对于double,直接把熟悉的小数表示赋值给变量即可,例如:
1 | double d = 333.33; |
但对于float,需要在数字后面加大写字母F或小写字母f,例如:
1 | float f = 333.33f; |
这是由于小数常量默认是double类型。
除了小数,也可以把整数直接赋值给float或double,例如:
1 | float f = 33; |
(3)真假类型
真假(boolean)类型很简单,直接使用true或false赋值,分别表示真和假,例如:
1 | boolean b = true; |
(4)字符类型
字符类型char用于表示一个字符,这个字符可以是中文字符,也可以是英文字符,char占用的内存空间是两个字节。赋值时把常量字符用单引号括起来,不要使用双引号,例如:
1 | char c = 'A'; |
大部分的常用字符用一个char就可以表示,但有的特殊字符用一个char表示不了。此外,关于char还有一些其他细节,我们在2.4节再进一步解释。
前面介绍的赋值都是直接给变量设置一个常量值,但也可以把变量赋给变量,例如:
1 | int a = 100; |
变量可以进行各种运算(1.3节介绍),也可以将变量的运算结果赋给变量,例如:
1 | int a = 1; |
前面介绍的赋值都是在声明变量的时候就进行了赋值,但这不是必需的,可以先声明变量,随后再进行赋值。
1.2.2 数组类型
基本类型的数组有3种赋值形式,如下所示:
1 | 1. int[] arr = {1,2,3}; |
第1种和第2种都是预先知道数组的内容,而第3种是先分配长度,然后再给每个元素赋值。第3种形式中,即使没有给每个元素赋值,每个元素也都有一个默认值,这个默认值跟数组类型有关,数值类型的值为0, boolean为false, char为空字符。
数组长度可以动态确定,如下所示:
1 | int length = ... ; //根据一些条件动态计算 |
数组长度虽然可以动态确定,但定了之后就不可以变。数组有一个length属性,但只能读,不能改。还有一个小细节,不能在给定初始值的同时给定长度,即如下格式是不允许的:
1 | int[] arr = new int[3]{1,2,3} |
可以这么理解,因为初始值已经决定了长度,再给个长度,如果还不一致,计算机将无所适从。
数组类型和基本类型是有明显不同的,一个基本类型变量,内存中只会有一块对应的内存空间。但数组有两块:一块用于存储数组内容本身,另一块用于存储内容的位置。用一个例子来说明,有一个int变量a,以及一个int数组变量arr,其代码、变量对应的内存地址和内存内容如表1-3所示。
基本类型a的内存地址是1000,这个位置存储的就是它的值100。数组类型arr的内存地址是2000,这个位置存储的值是一个位置3000,3000开始的位置存储的才是实际的数据“1, 2, 3”。
为什么数组要用两块空间?不能只用一块空间吗?我们来看下面这段代码:
1 | int[] arrA = {1,2,3}; |
这段代码中,arrA初始的长度是3, arrB的长度是4,后来将arrB的值赋给了arrA。如果arrA对应的内存空间是直接存储的数组内容,那么它将没有足够的空间去容纳arrB的所有元素。
用两块空间存储就简单得多,arrA存储的值就变成了和arrB的一样,存储的都是数组内容{4,5,6,7}的地址,此后访问arrA就和arrB是一样的了,而arrA {1,2,3}的内存空间由于不再被引用会进行垃圾回收,如下所示:
1 | arrA {1,2,3} |
由上也可以看出,给数组变量赋值和给数组中元素赋值是两回事,给数组中元素赋值是改变数组内容,而给数组变量赋值则会让变量指向一个不同的位置。
上面我们说数组的长度是不可以变的,不可变指的是数组的内容空间,一经分配,长度就不能再变了,但可以改变数组变量的值,让它指向一个长度不同的空间,就像上例中arrA后来指向了arrB一样。
给变量赋值就是将变量对应的内存空间设置为一个明确的值,有了值之后,变量可以被加载到CPU, CPU可以对这些值进行各种运算,运算后的结果又可以被赋值给变量,保存到内存中。数据可以进行哪些运算?如何进行运算呢?我们下节介绍。