大家好,我叫何先振,今天给大家讲解下Java的基本语法,变量部分。
1.变量的定义
第一讲我们说过,计算机的CPU运行时,需要从内存中拿数据,内存从硬盘中拿数据。内存从硬盘中拿到的数据被存在内存中,而变量就是内存里面的存储区域。该区域可以在同一类型数据的范围内不断变化,因此称为变量。他是我们程序中最基本的存储单元。
变量的组成包含变量类型、变量名、和存储在这个变量里面的值。如图:
运行结果如图所示:
这里有几个注意点:
注意1:代码中,方式二,变量必须先声明后使用。
注意2:变量只能在main方法{}括号内才能使用,如果在外面就会失效。因为我们声明这个变量是在main{}内声明的。这是变量的作用域,你在哪声明,作用域就在哪。
注意3:同一个作用域内,不能存在两个相同命名的变量。
变量的作用,就是用于保存内存中的数据。
2.变量的分类
变量的分类是针对每一种数据都定义了明确具体的数据类型,在内存中针对每种数据都分配了不同大小的内存空间。可分为基本数据类型、引用类型。
基本数据类型,可分为数值型、字符型、布尔类型。
1.数值型,可分为:整数型:byte、short、int、long类型。浮点型:float、double类型。
2.字符型,只有一个,char类型。
3.布尔类型,也只有一个,boolean类型。
引用数据类型:可分为类、接口、数组等:
类:class,其中String就是class类类型的数据类型。
接口:interface,后续会讲。
数组:{[]},后续会讲。
3.基本数据类型
(1)数值型:byte、short、int、long。他们的区别是占用内存的大小不一样。1byte(字 节)=8个bit(位),这个第一讲已经说过。一个字节,有8个位,每个位不是0就是1,那么他可以表示数的范围就是2的8次方,就是256.正负居中数的范围就是-128~127。如图:
如果超过了,就会报错。如图:
其他的,1个short类型内存大小等于2个byte字节,1个int是4个byte,1long是8个byte。开发中我们最常用的是int类型,通常long类型后面要加个L。如图:
(2)浮点型:float、double,数据都有小数点的。float被称为单精度,尾数可以精确到7位小数。很多情况下,精确度很难满足需求。double被称为双精度,精度是float的两倍,通常采用此类型。
大小区别:1个float等于4个字节,1个double等于8个字节。数值范围比long还要大。Java声明浮点类型时,默认为double类型,如果用float需要在后面加个f或者F。否则就会报错,如图:
当我们加了F后,就不会报错了。如图:
通常定义浮点类型使用double类型。
(3)字符型:char,内存大小1个char等于2个byte。通常定义使用 char c1='a';单引号定义,然后在单引号写个字符。如图:
注意只能写一个字符,否则编译不通过。如图:
除了表示一个字符,char可以表示转意字符。例如换行符:\n
\t制表符:
\u 使用Unicode值表示字符常量:
谈到使用Unicode值,这就要说到什么是字符集。
前面我们讲过,程序语言最底层的就是机器语言,也就是二进制制语言,由一堆0和1组成。我们写的这些Java程序代码都会在底层转成0和1的二进制机器语言。如何转换成二进制呢?其中就有个字符集做为中间层,当我们写了个代码c的字符,字符集就会把这个字符C,变成一个特定的数值比如0043。然后再让0043去转换成0和1的二进制语言。而我们看到的代码,也是通过字符集,把这些对应的数值,转换成对应的值。比如0043,对应的就是C。
我们都知道,计算机起源于美国,最开始使用的字符集就是ASCII码。这是美国制定了一套字符编码规则,美国用的是英语,就对英语字符与二进制位之间的关系做了统一规定。英语字母有26个,加上大小写共有52个,再加上一些其他特殊字符,本身并不多,所以ASCII码一共规定了128个字符的编码。比如大写的A代表的是65,小a代表的是97。
乱码问题:后面互联网传遍全世界,每个人都想用计算机,而每个国家的语言却不一样,我们中国的汉字就不止26个,所以就需要使用更大的字符集。每个国家的语言,都会有个自己国家的字符集。但是这样就会导致语言跟语言之间,互不相同,比如在英语系字符集a代表是97,到了法语系的字符集就代表120。本来一个有意义的文字,就变成了乱码了。
世界上存着多种编码方式,同一个二进制数字可以被解析成不同的符号。因此,要想打开同一份文本文件,就必须知道他的编码方式,否则用错误的编码方式解读,就会出现乱码的问题。
为了更好的解决这个问题,这时候就需要一个字符集,把全世界的语言都统一起来,都含盖在这个字符集中。Unicode就是一种编码,将世界上所有的符号都纳入其中,使用Unicode就可以支持多种语言。
而现在互联网使用最广的是UTF-8,它是Unicode的一种实现方式。我们编写代码用的是UTF-8保存,到了其他语言也用这种UTF-8解析就没乱码问题。上讲我们编写第一个程序的时候,就出现了编写中文就会出现乱码问题,就是因为我们保存用的是UTF-8,但是我们命令行解析用的是GBK字符集,两种字符集不一样就会导致出现乱码问题。要想不出现乱码问题,就要确保保存代码的字符集规则与解析代码的字符集规则一致。
关于字符集就介绍到这里了,详细关于计算机字符编码的知识,有兴趣的可以网上了解下。这里就不再深入讲解了。
(4)布尔型:boolean只能取两个值之一,要么是false,要么是true。常常在我们的控制语句中使用,比如if判断,循环语句中使用。如图:
4.基本数据类型变量间转换
介绍完基本数据类型,下面我们就来了解下,基本数据类型变量间的转换。可以分为两种:一种是自动类型提升,一种是强制类型转换。
自动类型提升,byte、short、int、long、float、double中当容量小的数据类型和容量大的数据类型做运算时,结果自动提升为容量大的类型。这里的容量大小,只是这个数据类型表示数的范围容量大小,而不是占用内存空间的容量大小。比如float的容量要大于long的容量。
int比byte的表示数范围要大,所以要用int类型接收,如图:
如果用容量小的数据类型接收,会报错,因为容量小的接收,会出现容量不足,导致数据可能会损失。如图:
当我们用字符型做运算时,发现char跟byte、int、short做运算时,结果都是int。因此这里可以再次说明一点,当用byte、char、short三种变量类型做运算时,结果为int类型,要用int做接收。
如果用其他类型,都会报错,报错提示语句:从int转换成char,说明最终用int接收。如图:
不光是跟其他类型做运算,也包括自身比如byte+byte,也需要用int接收。如图:
说完自动类型提升,下面我们来介绍下,什么是强制类型转换。
强制类型转换,也叫自动类型提升的逆运算,就是往小的容量的数据类型上转换。容量大的跟容量小的做运算不让它自动提升到容量大的,让它提升到容量小的数据类型上。
强制类型转换,需要使用强转符:()括号内填写的是需要强转的数据类型。强制转换可能会导致精度损失。
double类型强转成int类型,出现精度损失(原先是1243.5),转化后变成1243。如图:
long转成int类型,不会出现精度损失,因为本身int数的范围包含了,此时long变量的数值不变。如图:
int转byte时,如果超过了byte类型数的范围,就会出现精度损失。至于损失后的精度为什么是-128,后面讲进制时,我们再来说。如图:
变量运算的两个特殊情况说明:
如果定义long类型变量,变量值后面没有加L默认为int类型,而int类型自动提升为long类型,这时如果超过了,int的数值范围长度,就会报错,必须要在变量值后面加上L,你不加还不报错是因为你的长度没有超过int的范围。定义整数默认不加都是int类型。如图:
加上L,编译时没有报错,如图:
如果定义了float类型变量,必须要在后面加f,因为写小数,默认会是double。double转float强转没有加强转符,就会报错。如图:
加了f后编译成功,没有报错。如图:
常量是整数默认是int,常量是小数,默认是double,如果用float去接收会失败,因为你没在后面加f。加了f后编译成功,如图:
5.基本数据类型与String间的转换
讲完基本数据类型的转换,下面我们介绍下基本数据类型与String间的转换。String属于引用数据类型,翻译为:字符串。声明String类型变量时,使用一对"",如图:
String可以和8种基本类型做运算,只能做连接运算,连接符用+号。String运算的结果,依然是String。如图:
6.进制与进制的转换
上面我们还遗留了一个问题就是int转byte时,如果超过了byte类型数的范围,就会出现精度损失。至于损失后的精度为什么是-128。这里就要涉及到进制与进制转换的问题了。下面就简单介绍下,进制和进制间的转换问题。
关于进制的介绍,所有数字在计算机底层中都以二进制形式存在。
对于整数,有四种表示方法:
二进制:0和1表示,满2进1,以0b或者0B开头。
十进制:0到9表示,满10进1。
八进制:0到7表示,满8进1,以数字0开头表示。
十六进制:0到9以及A到F,满16进1,以0x或者0X开头表示。此处的A-F不区分大小写。比如:0x21AF+1=0x21B0
让我们看下代码中如何表示,如图:
下面我们先来说二进制和十进制的转换。
因为1个字节有8个位,每一位都可以存0或者1,从低位到高位。1表示1,表示2时向高位进1表示10,3表示11,4也要向高位进1表示100,5表示101,6表示110。这也就说明上面的代码ob110等于6。
2进制的计算公式:从低位到高位,第几位出现1,就是1*2^的第几位-1,然后累加,比如0b110,由低位到高位出现了一个0两个1,第一个0在第一位上,可以写成0*2^0等于0不计,第一个1在第二位上,所以为1*2^1,第二个在第三位上为1*2^2次幂累加起来,就是1*2^2+1*2^1=6
下面我们看看二进制负数如何表示,负数表示就要知道什么是原码、什么是反码、什么是补码。
表示正负,内存中用最高位,表示正数和负数。0表示正数,1表示负数。比如:00000110表示6,10000110表示负数,也是-6的原码。-6的反码就是除了第8位,其他位取反,得到11111001表示-6的反码。-6的补码就是反码+1,得到11111010,这是-6的补码。
计算机底层都以补码的方式存储数据,正数的原码、反码、补码都一样。负数的原码,就是正数最高位改为1,反码就是原码除最高位其他位取反,补码就是反码+1。
上面强转类型说到,int类型的128转成了byte类型,就是因为127 的二进制为01111111,转化为-127,先算原码11111 111,然后取反求反码,10000 000,然后加1,补码为:10000 001这是-127,在减1就是-128,10000 000,当int为转128时,int为4个字节,也就是有32位。当转换成byte时,就剩下8位了,最高位正好是代表符号位,因此就表示-128了。
二进制转十进制,那么十进制怎么转二进制呢?规则:让十进制除2取余的逆。比如13:
-
13除以2,商6余1
-
6除以2,商3余0
-
3除以2,商1余1
-
1除以2,商0余1
-
0除以2,商0余0
-
后面余数都是0
-
得到余数结果:10110000
-
取逆得到:00001101 这是13的二进制
二进制转八进制介绍:低位到高位,每三个位,求一次2^(n-1)的幂的累加,其中n代表第几位。比如110110,看成是两个110,110,一个110为1*2^2+1*2^1=6,那么八进制就是066。八进制最大的数,就是三个位都为1,为111,就是1*2^2+1*2^1+1*2^0=7。
八进制转二进制介绍:反过来,把每个八进制的数,拆成3位。比如034为011=3 ,100=4,最后得到011100。
二进制转十六进制介绍:同八进制一样,就是从低位到高位,把4个看成一个数,最大值就是4个1,为1111,也就是2^3+2^2+2^1+2^0=15,也就是F。
十六进制转二进制介绍:反过来,把每个十六进制的数,拆成4位,比如0xAF ,A=1010,F=1111,最后得到10101111。
这个进制的转换,只是做个了解,后面如果具体要你转换的话,我们的java都提供了api给你,只需要调用对应的api就可以进行转换了。
以上就是这期的全部内容,看更多内容请点击关注。下期我们讲解Java基本语法之运算符部分。