一、强类型语言和弱类型语言:
1.1 强类型语言
强类型语言是一种强制类型定义的语言,一旦某一个变量被定义类型,如果不经过强制转换,则它永远就是该数据类型了,强类型语言包括Java、.net 、Python、C++等语言。
强类型包含两个方面:
(1)所有变量必须先声明、后使用
(2)指定类型的变量只能接受类型与之匹配的值
举个例子:定义了一个整数,如果不进行强制的类型转换,则不可以将该整数转化为字符串。
1.2 弱类型语言
弱类型语言是一种弱类型定义的语言,某一个变量被定义类型,该变量可以根据环境变化自动进行转换,不需要经过显性强制转换。弱类型语言包括vb 、PHP、javascript等语言。
举个例子:
var A =5; var B = "5"; SumResult = A +B; MinResult = A -B;
输入SumResult的答案不是10,而是55,再次是将A的类型转化为了字符串,然后进行拼接。输入MinResult的答案是0,是将B的类型转化为了数字,然后进行减法。
1.3 强类型语言和弱类型语言区别
无论是强类型语言还是弱类型语言,判别的根本是是否会隐性的进行语言类型转变。强类型语言在速度上略逊于弱类型语言,但是强类型定义语言带来的严谨性又能避免不必要的错误。
二、Java数据类型分类
Java数据类型可以分为两类:基本类型(Prmitive Type)和引用类型(Reference Type)
2.1 基本类型
基本类型包括 boolean 类型和数值类型。数值类型有整数类型和浮点类型。整数类型包括 byte、 short、int 、 long 、 char , 浮点类型包括 float 和 double 。
注:char类型代表字符型,实际上也是一种整数类型,相当于无符号整数类型。
2.2 引用类型
引用类型包括类、接口和数组类型,还有一种特殊的 null 类型 。 所谓引用数据类型就是对一个对象的引用,对象包括实例和数组两种 。实际上 ,引用类型变量就是一个指针,只是Java语言里不再使用指针这个说法。
空类型 (null type ) 就是 null 值的类型 , 这种类型没有名称。因为 null 类型没有名称 ,所以不可能声明一个 null 类型的变量或者转换到 null 类型。空引用 (null ) 是 null 类型变量唯一的值。空引用 ( null )可以转换为任何引用类型 。
在实际开发中 , 程序员 可以忽略 null 类型 ,假定 null 只 是引用类割的一个特殊直接量。
注意:空引用( null )只能被转换成引用类型 , 不能转换成基本类型,因此不要把一个 null值赋给基本数据类型的变量 。
三、基本数据类型
Java基本数据类型分为两类:boolean类型和数值类型。而数值类型又可以分为整数类型和浮点数类型,整数类型里的字符类型又可以被单独对待。因此常把Java数据类型分为4类:
3.1 整型
4种整数类型:
(1)byte:一个byte类型整数在内存里占8位,表示整数范围:-128(-27)~127(27-1)
(2)short:一个short类型整数在内存里占16位,表示整数范围:-32768(-215)~32767(215-1)
(3)int:一个int类型整数在内存里占32位,表示整数范围:-2147483648(-232)~2147483647(232-1)
(4)long:一个long类型整数在内存里占64位,表示整数范围:--264~264-1
int 是最常用 的 整数类型,因 此 在通常情 况下, 直接给出一个整数值默认就是 int 类型。除 此 之 外,
有如下两种情形必须指出。
如果直接将一个较小的整数值(在 byte 或 short 类型的表数范围内〉赋给一个 byte 或 short 变量 ,系统会自动把这个整数值当成 byte 或者 short 类型来处理 。
如果使用 一个巨大的整数值(超出了 int 类型的表数范围)时 , Java 不会自动把这个整数值当成long 类型来处理。如果希望系统把 一 个整数值当成 lon g 类型来处理,应在这个整数值后增加 l或者 L 作为后缀 。通常推荐使用 L,因为英文字母 l 很容易跟数字 1搞混 。
下面的代码片段验证了上面的结论 。
1 public class Test{ 2 public static void main(String[] args){ 3 //下面代码正确,系统会把56当作byte类型处理 4 byte a =56; 5 System.out.println(a); 6 /* 7 下面用法错误,系统不会把99999999999999当成long类型来处理 8 所超出int的表数范围,从而引起错误(换种理解:999999999999是一个int型的变量,超出了int类型的变量的范围,所以不能直接赋给long变量) 9 报错:过大的整数99999999999999 10 */ 11 //long bigValue=99999999999999; 12 //下面用法正确,在巨大的整数后面L后缀,强制使用long类型 13 long bigValue=99999999999999L;//99999999999999L是一个long变量,并未超出long的变量的范围,可以赋给long型变量Bigvalue 14 System.out.println(bigValue); 15 } 16 }
运行结果:
可以把一个较小的整数值(在 int 类型的表数范围以 内)直接赋给一个 long 类型的变量,这并不是因为 Java 会把这个较小的整数值当成 long 类型来处理, Java 依然把这个整数值当成 int 类型来处理,只是因为 int 类型的值会自动类型转换到 long 类型 。
Java整数值的4种表现形式:
十进制
二进制(以0b或0B开头)
八进制(以0开头)
十六进制(以0x或0X开头)
1 public class system{ 2 public static void main(String[] args){ 3 //以0开头的整数表示八进制 4 int octalValue=012; 5 System.out.println(octalValue); 6 //以0x开头的表示为十六进制 7 int hexValue=0x12; 8 System.out.println(hexValue); 9 //二进制数表现 10 int binValue=0b10000000; 11 System.out.println(binValue); 12 //定义 32 位的二进制整数时,最高位其实是符号位,当符号位是 l 时 , 13 //表明它是一个负数,负数在计算机里是以补码的形式存在的 ,因此还需要换算成原码。 14 15 long binValue1=0b11111111111111111111111111111111; 16 System.out.println(binValue1); 17 } 18 }
输出结果:
在计算机中所有的数都是以二进制表示的,binValue1=0b11111111111111111111111111111111
转换为原码的过程:
补码:0b11111111111111111111111111111111
补码减1得到反码:0b11111111111111111111111111111110
符号位不变,其余位取反得到原码:0b1000000000000000000000000000000001
最后的结果为负,数值为1
3.2 字符型
字符型通常用于表示单个的宇符 ,字符型值必须使用单引号 (,)括起来。 Java 语言使用 16 位的Unicode 字符集作为编码方式 ,而 Unicode 被设计成支持世界上所有书面语言的字符 ,包括中文字符 ,因此Java 程序支持各种语言的字符。
字符型有三种表示形式:
(1)直接通过单个字符来指定字符值,例如'A','9','0'等。
(2)通过转义字符表示特殊的字符型,例如'\n'、'\t'等。
(3)直接使用Unicode值来表示字符型,格式是'\uXXXXX',其中XXXX代表一个十六进制的整数。
Java常用转义字符:
转义字符 | 说明 | Unicode表示方式 |
\b | 退格符 | \u0008 |
\n | 换行符 | \u000a |
\r | 回车符 | \u000d |
\t | 制表符 | \u0009 |
\'' | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜线 | \u005c |
宇符型值也可以采用十六进制编码方式来表示,范围是'\u0000'~'\uFFFF' , 一共可以表示 65536 个字符,其中前 256 个 ('\u0000'~'\u00FF' ) 字符和 ASCII 码中的字符完全重舍 。由于计算机底层保存字符时,实际是保存该字符对应的编号 ,因此 char 类型 的值也可直接作为整型值来使用 , 它相当于一个 16 位的无符号整数 , 表数范围是 0~65535 。
注意:char类型的变量值完全可以参与力加、减、乘、除运算,也可以比较大 小—— 实际上都是用该字符对应的编码参与运算。如果把0~65535一个int整数赋给char类型变量,系统会自动把这个int整数当成char类型来处理。
字符变量使用:
1 public class CharTest{ 2 public static void main(String[] args){ 3 //直接指定单个字符作为字符型 4 char aChar='a'; 5 //使用转义字符作为字符集 6 char enterChar='\r'; 7 //使用Unicode编码值来指定字符值 8 char ch='\u9999'; 9 System.out.println(ch); 10 //定义一个汉字的字符值 11 char zhong='汉'; 12 int zhongValue=zhong; 13 System.out.println(zhongValue); 14 char c=97; 15 System.out.println(c); 16 } 17 }
3.3 浮点型
Java浮点型有两种:float和double。Java浮点型有固定的表数范围和字段长度,字段长度表数范围与机器无关。Java浮点数,遵循IEEE754标准,采用二进制数据的科学计数法表示。
对于float型整数:第1位是符号位,接下来8为表示指数,在接下来23位表示尾数
对于double型整数:第1位是符号位,接下来11为表示指数,在接下来52位表示尾数
Java语言的浮点数两种表示形式:
1、十进制数形式:这种形式是最简单的浮点数,例如5.12,512.0,.512.浮点数必须包含一个小数点,否则会被当做int类型处理。
2、科学计数法形式:例如5.12e2或5.12E2
必须指出的是,只有浮点类型的数值才可以使用科学计数法形式表示。例如, 51200 是一个 int 类型的值 , 但 512E2 则是浮点类型的值 。
Java语言浮点数的默认类型是double类型,如果希望Java把一个浮点数当成float处理,应该在这个浮点类型值后跟一个f或F。例如5.12代表一个double类型的值,占64位的内存空间;5.12f或5.12F才表示一个float类型的值,占32位的内存空间。也可以在一个浮点数后添加d或D后缀,强制指定为double类型,但通常没有必要。
Java提供了三种特殊的浮点数类型值:正无穷大、负无穷大和非数,用于表示溢出或出错。例如用一个正数除以0将得到正无穷大,使用一个负数除以0将得到负无穷大,0.0除以0.0或对一个负数开根号将得到一个非数。正无穷大通过double或float类的POSITIVE_INFINITY表示;负无穷大通过NEGATIVE_INFINITY表示;非数通过double或float类的NaN表示。
必须指出的是,所有的正无穷大数值都是相等的,所有的负无穷大数值都是相等的 : 而 NaN不与任何数值相等 , 甚至和 NaN 都不相等 。只有附带念书除以0才可以得到正无穷大或负无穷大,因为Java语言会自动把和浮点数运算的0(整数)当成0.0(浮点数)处理。如果一个整型值除以0,则会抛出一个异常:ArithmeticException:/by zero
程序示范:
1 public class FloatTest{ 2 public static void main(String[] args){ 3 /* 4 浮点数表示的5.2345678f,输出这个变量值已经发生改变 5 使用double型表示比浮点数更加精确,但如果浮点数的精度过高,依然可能发生输出结果不一致 6 如果需要精确的保存一个浮点数,则可以考虑使用BigDecimal类 7 */ 8 float af=5.2345678f; 9 System.out.println(af); 10 11 //所有正无穷大或负无穷大都是相等的 12 double a=0.0; 13 double b=Double.NEGATIVE_INFINITY; 14 double c=Float.NEGATIVE_INFINITY; 15 System.out.println(b==c); 16 System.out.println(6.0/0==555.0/0); 17 18 //0除以0.0(默认会将0当作浮点数来处理)将出现非数 19 System.out.println(0/a); 20 21 // 下面代码将抛出除以 0 的异常,只有浮点数除以0才能得到正无穷大或负无穷大 22 System.out .println(0/0); 23 } 24 }
*数值中使用下划线分隔
Java 7 后允许在整形数值、浮点数值中使用下划线(_)来分割数据来更清晰地看清数值的位数。
3.4 布尔型
布尔型只有一个boolean类型,用于表示逻辑上“真”或“假”。在Java语言中,boolean类型的数值只能是true或false,不能用0或者非0来代表。其他数值类型也不能转化成boolean类型。虽然 boolean 类型‘的变量或值只要1位即可保存,但由于大部分计算机在分配内存时允许最小内存单元是字节( 8 位) , 因此 bit 大部分时候实际 上占用 8 位 。
1 public class BooleanTest{ 2 public static void main(String[] args){ 3 boolean b1=true; 4 boolean b2=false; 5 System.out.println(b1); 6 7 //字符串"true"和"false"不会直接转化成boolean类型,但如果使用一个boolean类型的值 8 //和字符串进行链接运算,则boolean类型的值会自动转化成字符型 9 String str=b1+""; 10 System.out.println(str); 11 } 12 }
boolean类型的变量或值主要用来做标识来进行控制流程(if语句、循环语句、三目运算符)。
3.5 使用·var定义变量
Java 10开始支持var定义局部变量:var相当于一个动态类型,使用var定义局部变量的类型由编译器自动推断——定义变量时分配了什么类型的初始值,那么该变量就是什么类型。但Java属于强类型语言,因此使用var定义变量依然没有明确的类型。只有为局部变量指定初始值时,该变量的类型才确定下来。
使用var的优点在于:编码更简洁,不管什么类型的局部变量,直接使用var声明即可;缺点在于:变量类型的可读性降低了。
以下情况,应该避免使用var定义局部变量:
(1)变量的类型不容易直接判断
(2)局部变量的使用范围很大