Java数据类型和运算符
Java数据类型和运算符
Java是一门强类型语言,所谓的强类型语言,可以理解为包含以下2层含义:
1.所有的变量都必须先声明,后使用
2.变量的类型一旦确定,那么变量的值必须和数据类型相匹配
变量:可以理解为程序运行时内存中用于保存数据的一个存储区域,该存储区域有自己的名称、类型、和值。强类型语言可以在编译过程中发现源代码的错误,从而保证程序更加健壮。
标识符和关键字
Java中将变量名和方法名以及类名统称为标识符,标识符命名规则如下:
1.标识符只由字母、数字、下划线(_)、和美元符号($)组成,但是不能以数字开头
2.标识符不能是Java的关键字和保留字、但是可以包含关键字和保留字
3.标识符不能包含空格以及其他特殊符号
标识符命名方式
在Java中标识符的命名一般遵循以下两种命名方式:
1.Pascal命名法:所有单词的首字母均大写,例如StudentName,TeacherAge,这种命名法通常用于类名。
2.Camel命名法:第一个单词的首字母小写,其余单词首字母均大写。例如:productName,produceCount。这种命名法通常用于变量名及方法名。
数据类型分类
Java中数据类型可以分为两大类:基本类型和引用类型。其中基本类型又可以分为4类,分别是:整型、浮点型、布尔型和字符型
整型
整型通常包含以下4种:
byte: 一个byte类型整数在内存中占8位(bit)即1个字节,可以表示的数值范围为:-128一127
short: 一个short类型整数在内存中占16位即2个字节,可以表示的数值范围为-2^15一一2^15-1
int: 一个int类型整数在内存中占32位4字节,可以表示的数值范围为-2^31一2^31-1
long: 一个long类型整数在内存中占64位8字节,可以表示的数值范围-2^63一一2^63-1
如果直接将一个较小的整数值(byte或者short类型的表示范围内)赋值给一个byte类型或者short变量,系统会自动把这个整数值当成byte或者short类型处理,因为在Java中定义一个整型变量。编译器会默认是int类型
如果使用一个巨大的整数值(超出了int类型能表示的范围),Java不会自动把这个整数当成long类型处理,如果希望编译器把这个正式当做long类型处理,应该在数值后添加”l”或者”L”.
变量的声明
在Java中声明一个变量必须先指定数据类型(Java11之前),并对其进行初始化
变量的初始化
声明一个变量时,目的就是为了在变量中保存数据,并使用该数据。因此,当变量定义完毕后,需要对其进行初始化,所谓初始化,就是在为变量开辟的内容空间中保存一份数据。
1 | //定义一个byte类型的变量 |
Java中整数值有4种表示方式:十进制、二进制、十六进制、八进制,其中二进制的整数以0b或者0B开头;八进制的整数以0开头;十六进制的整数以0X或者0x开头,其中10-15分别以a-表示。
1 | //二进制 |
浮点型
Java中浮点型有两类:float和double.。Java的浮点型有固定的表示范围,Java的浮点数遵循1EEE754标准,采用二进制数据的科学计数法来表示浮点数,对于float类型,第1位是符号位,接下来的8位表示指数,在接下来的23位表示尾数;对于double类型的值,第1位也是符号位,接下来的11位表示指数,再接下来的52位表示尾数。
Java中浮点型有两种表示形式:
十进制:这种形式就是简单的浮点数,如:3.14,7.1等浮点型必须包含一个小数点,否则会被当成int类型处理
科学计数法:例如5.12e2(即5.12x102)
Java语言中浮点型默认的都是double类型的,如果要让Java把一个浮点数当故float类型处理,应该在这个浮点型后面添加后缀f或者F
1 | //定义一个浮点型 |
Java还提供了三个特殊的浮点数:正无穷大、负无穷大和非数,用于表示益出和出错。正无穷大用POSITIVE _INFINITY表示;负无穷大用NEGATIVE_INFINITY表示,非数通过NAN表示
1 | double d1 = 0.1; |
注意:所有的正无穷大都是相等的,所有的负无穷大都是相等的,但是NAN与任何数值都不相等,甚至和NAN都不相等。另外,只有浮点数除以0才可以得到正无穷大或者负无穷大,如果一个整数除以0,则会抛出一个异常(算数异常:ArithmeticException: / by zero)
字符型
字符型通常用于表示单个字符,字符型值必须要用单引号括起来,Java语言使用16位的Unicode字符集作为编码方式,而Unicode字符集支特世界上所有书面语言的字符,包括中文字符因此Java程序支持各种语言的字符。
字符型值有3种表示形式
·通过单个字符来指定字符型值:例如A’,’9等
·通过转义字符表示特殊字符型值,如’\n’,”\t’等:
·直接使用Unicode值来表示字符型格式为’\uxxxx’,其中xxxx表示一个十六进制的整数
Java中常用转义字符如下表:
字符型值也可以使用十六进制的编码方式表示,范围是u0000一一\uFFFF,一共可以表示65535个字符,其中前256个字符和ASCII码中字符一致。并且char类型也可以作为整型值使用
布尔型
布尔型只有boolean类型,用于表示逻辑真和假,在Java中布尔型的值只有true或者false,且不能用0或者非0表示。和其他数据类型也不能相互转换.
Java规范中并没有强制指定布尔型变量所占用的内存,即使布尔型变量只要1位就可保存,但是大部分计算机在分配内存时所允许的最小内存单元是字节,因此布尔类型实际上占用了8位
基本类型转换
在java应用中,经常需要不同数据类型之间进行相互转换,布尔型和其他类型不能相互转换,但是在剩余7种类型之间可以相互转换,转换方式有两种:自动类型转换和强制类型转换
自动类型转换
Java中当把一个表示范围小的数值或变量赋值给另一个表示范围大的变量时,系统将自动进行转换,反之则需要强制转换。
箭头左边的数值类型可以自动转换为箭头右边的数值类型。
1 | public class TypeCast1 { |
强制类型转换
表示范围大的值或变量赋值给表示范围小的变量时,需要进行强制转换
1 | public class TypeCast2 { |
上例中我们发现当我们把浮点型转成整型时,发生了精度丢失,只保留了整数位,舍弃了小数位,因此当操作此种类型转换时一定要注意精度丢失的问题。并且当我们把int类型转成char类型打印时发现打印了a,因为java使用了Unicode:字符集,并且前256位兼容了ASCII码,而97正是字符a。
自动类型提升
当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生自动提升,java自动提升规则如下:
所有的byte、short、和char类型将被提升到int类型
整个算术表达式的数据类型自动提升到表达式中最高等级操作数相同的类型
1 | //定义一个byte类型变量并+2 |
编译上述代码时会发现编译无法通过,这是因为变量s是short类型,2则是int类型,此时表达式中包含了多个数据类型,那么该表达式结果的数据类型则会发生自动提升,提升为最高等级操作数数据类型,也就是int,此时将一个int类型的值赋值给short类型的变量,需要进行类型强制转换,上述代码中并未强制转换,因此会编译错误,如果对s+2强制转换为int类型,则会编译通过并正常运行。
1 | //定义double类型变量 |
在上例代码表达式中包含double类型、int类型、byte类型,根据Java类型自动提升的规则,我们知道表达最终的运算结果为等级最高的数据类型,也就是double类型,因此我们最后保存结果时定义了double类型的变量。
Java中的基本数据类型以及每种类型所占用的字节数和取值范围:
运算符
编程语言主要的功能之一就是进行或简单或复杂的运算,在运算过程中有操作数,同样也需要运算符的参与,运算符其实就是一种特殊的符号,用于表述数据的运算,赋值和比较等。
Java中运算符可以分为以下几类:
·算术运算符(加、减、乘、除、取余、自增自减)
·%:取余运算符,求余是指使用第一个操作数除以第二个操作数,得到一个整除的结果后剩下的就是余数。需要注意的是求余运算,本质上也是一个除法运算,如果求余运算的两个操作数都是整型,则第二个操作数不能为0,
否则会引发程序异常。如果求余运算的两个操作数中有1个或者2个都是浮点数,则第二个操作数可以是0或者0.0,结果是NAN。0或者0.0对零以外的任何数求余都会得到0或者0.0.
1 | public class ModDemo { |
·赋值运算符 (=)
·比较运算符(>、 <、 >=、 <=、==)
·逻辑运算符
·位运算符
·类型相关运算符
位运算符
Java中位运算符有7个:
&:按位与。当两位同时为1时才返回1(同1为1)。
|:按位或。只要有一位为1时即返回1(有1则1)。
~:按位非。单目运算符,将操作数每一位(包括符号位)1变0,0变1(符号位一起取反加一)
^:按位异或。当两位相同时返回0,不同时返回1。(相同为0,不同为1)
<<:左移运算符(左移为乘)
·>>:右移运算符
·>>>:无符号右移运算符
一般来说,位运算只操作整数类型的变量或值。
逻辑运算符
逻辑运算符用于操作两个布尔型的变量或者常量,主要有以下6个。
·&&:与,左右两个操作数都是true才会返回true,否则返回false,需要注意的是如果左右两边是表达式,如果第一个表达式就返回false,则第二个表达式并不进行运算。
·&:不短路与,作用于&&相同,但是无论第一个表达式的结果是true还是false,第二个表达式都会进行运算。
·||:或,两个操作数只要有一个为true,就可以返回true,否则返回false,同样,如果第一个表达式返回值为true,则第二个表达式不进行运算
·|:不短路或,作用于相同,但是无论第一个表达式结果如何,第二个表达式都会进行运算。
·!:非,只需要一个操作数,如果操作数为true,则返回false,如果操作数为false,则返回true。
·^:异或,当两个操作数不同时返回为true,如果两个操作数相同的返回false。
三目运算符
三目运算符只有一个:?:,三目运算符语法格式如下:
(expression) ? if-true-statement : if-false-statement;
运算规则如下:
1.计算表达式expression的值
2.如果表达式返回true,则返回if-true-statement的值
3.如果表达式返回false,则返回if-false-statement的值
赋值扩展运算符
赋值运算符可以同算术运算符、位移运算符结合,对赋值运算符进行扩展,扩展后的赋值运算符如下:
·+=:对于x+=y,等价于x=x+y。
·-=:对于x-=y,等价于x=x-y。
·*=:对于x*=y,等价于x=x*y。
/=、%=、&=、|=、^=、<<=、>>=、>>>=(无符号右移赋值操作)
运算符优先级
运算符有不同的优先级,所谓优先级就是在表达式中运算的先后顺序,Java语言中大部分运算符都是从左向右结合的,只有个别运算符从右向走结合,例如:单目运算符、赋值运算符、三目运算符,下表将列出所有运算符的优先级: