阅读原文
Java语言是强类型(strongly typed)语言,对于强类型语言有两大特点:
1、所有的变量必须先声明后使用。
2、指定类型的变量只能接受指定类型与之匹配的值。
这也就意味着强类型的语言语法更加的严格,对开发人员的要求也就更高了。
数据类型
在讨论数据类型前,先了解一下变量这个概念,什么是变量呢?
编程的本质就是对内存中的数据进行操作。程序所用的数据都会保存在内存中,程序员需要一种机制来对内存中的数据进行操作,比如获取、修改等。这种机制就是变量,程序中的每一个变量都代表了某一小块内存,而且变量是有名字的,程序对变量赋值,实际上就是把数据装入该变量所代表的内存区的过程;程序读取变量的值,实际上就是从该变量所代表的内存区取值的过程。形象的理解:变量相当于一个有名称的容器,该容器用于装各种不同类型的数据。
Java的数据类型分为两大类:基本数据类型(primitive type)和引用数据类型(reference type);基本数据类型又分为四大类:整数类型、字符类型、浮点类型、布尔类型;引用类型包括类、接口、数组以及一个特别的引用类型null类型四种,其中null类型没有具体的类型名称,null值作为null类型的唯一引用,可以转换为任何引用类型,关于Java数类型分类如下图:
整型
Java中整型包含以下四种类型:
注意:int是最常用的整数类型,因此通常情况下,直接给出一个整数值默认就是int类型。在定义long类型时需加后缀L或者l,由于小写l与数字1很相似,为了避免混淆,建议在开发中使用L。
栗子
/**
*定义整数类型
*/
byte b = 1;
short s = 1;
int i = 1;
long l = 1L;
Java中的整数值有四种表示方式,二进制、八进制、十进制以及十六进制,其中二进制以0b开头,八进制以0开头,16进制以0x开头,从JDK7开始java支持了二进制数对整数的支持。
栗子
/**
*分别用二进制、八进制、十进制、十六进制表示16及-16这两个个整数值
*/
//二进制
int d1 = 0b00000000000000000000000000010000;//正数
int _d1 = 0b11111111111111111111111111110000;//负数
//八进制
int d2 = 020;//正数
int _d2 = 037777777760;//负数
//十进制int d3 = 16;//正数
int _d3 = -16;//负数
//十六进制int d4 = 0x0010;//正数
int _d4 = 0xFFFFFFF0;//负数
在计算机中所有的的整数都是以二进制补码的形式存在的,正数的补码是其本身,负数的补码是其绝对值的原码求反码再加1.对于其他进制的负数可根据二进制数与其他进制间的转换规则将其求出即可。
字符型
字符型通常表示单个字符,用单引号(’)引起来。Java语言采用16位的Unicode字符集作为编码方式,而Unicode被设计成支持世界上所有书面语言的字符,包括中文字符,因此Java程序支持各种语言的字符,所谓字符集就是所有就是对所有字符的编号组成总和。
字符型值有三种表示方式
1、直接使用单个字符表示字符型值;
2、使用转义字符表示特殊字符型值;
3、使用Unicode编码表示字符型值;
栗子
//直接使用单个字符型值A
char c1 = 'A';
//使用转义字符表示双引号
char c2 = '\"';
//使用Unicode的编码表示‘你’
char c3 = '\u4f60';
Java语言中常用的转义字符
对于Unicode的码表,可以直接去问度娘,由于字符型值在计算机中也是以一个16位的无符号二进制来存的,所以char型变量也是可以参与运算的。
栗子
//将字符型值赋值给整型值,i1的输出应该是97
int i1 = 'a';
浮点型
Java的浮点型有两种:float和double。Java的浮点类型有固定的范围和长度,字段长度和表数范围与机器无关。Java的浮点数遵循IEEE754标准,采用二进制数据的科学技术法来表示浮点数,对于float型数值,第一位为符号位,接下来8位表示指数,再接下来的23位表示位数;对于double类型数值,第一位也是符号位,接下来11位表示指数、再接下来的52位表示尾数。
Java中的浮点型默认是double类型,如果想用float表示则需在所要表示的浮点数加后缀f或者F,double类型所占内从空间为64位,8个字节,float类型所占内存空间为32位4个字节,Java还提供了三个特殊的浮点类型值:正无穷大(Infinity)、负无穷大(-Infinity)以及非数(NaN)。
Java中浮点类型有两种表示方式:十进制数表示方式,如100.01以及十进制的科学技术法形式,如1.0001E2。
什么时候才会产生以上所述的三种特殊的浮点型呢?
正无穷大(Infinity):一个正的浮点数除以0或0.0;
负无穷大(-Infinity):一个负的浮点数除以0或0.0;
非数(NaN):0.0除以0或者0.0;
栗子
float f = 2.6666666666666666666666f;//精度丢失
double d1 = 0.1/0;//正无穷大
double d2 = -0.1/0;//父无穷大
double d3 = -0.0/0;//非数
double d4 = 100.01;// 十进制数表示浮点型
double d5 = 1.0001e2;//二进制数表示浮点型
关于浮点数精度的问题?
我们在之间的文章《进制间的转换》中提到,小数部分转换为二进制时,“乘二取整,顺序”,直到小数部分为零停止。但是要知道并不是所有的小数都能乘到小数部分为零。那么这个时候该如何处置?人为肯定是设置一个精度,根据精度取值,就跟我们除法保留几位有效数字是一样一样的。计算机其实也是如此,我们只需知道它有一个保留精度的标准即可。所以当我们定义的浮点数,小数部分位数越多,也就是要求的精度越高时,越容易丧失精度。而在Java的浮点数中,double的精度要高于float,如果您想要让浮点数更为精确表示,比如,你所要表示的是金额,那么Java专门提供了一个类(BigDecimal)来处理这种需求,关于这个类,会在后期的文章详细讲解。
小技巧:
这个小技巧只针对于数值类型的数据,假如我们要在程序中定义一个16位的二进制的整形变量或者浮点数,由于位数或者尾数过长,导致可能在编写的过中丢失数字,在Jdk1.7后Java可以采用下滑线(_)来对位数或者尾数进行划分,这样既便阅读程序又不容易出错,但是在实际的开发中用途不大。
栗子
int b = 0b1101_0000_1111_1000;
double d = 0.12_13_14_15_16_17_18_19;
布尔型
Java中布尔型只有一种boolean类型,且boolean类型的值只有两个true(真)或者false(假)。boolean类型在计算机中所占内存理论上只需一位即可,因为它要么是0要么是1,但是由于计算机分配内存的最小单元是字节,所以boolean在内存中占据一个字节(8位)。
栗子
//定义布尔类型
boolean flag1 = false;
boolean flag2 = true;
基本类型转换
Java基本数据类型的转换方式有两种:自动转换和强制转换。
自动转换
自动转换遵循原则是:表示数值范围小的类型会自动转为表示范围大的类型。范围:byte–>short–>int–>long–>float–>double,从左到右范围依次增大。这里需要注意的是char类型也可以自动转换,char–>int–>long–>float-double。
栗子
int i = 'a';//字符型自动转为整型
float f = 1;//整型自动转为单精度型
double d1 = 1.2f;//单精度型转为双精度型
double d2 = 'b';//字符型转为双精度型
强制转换
自动转换是计算机自动进行的,强制转换是程序员手动干预的,强制转换就是将大范围类型转为小范围类型,这个过程会产生精度丢失,所以在强制转时,一定要考虑到需要强转类型的值一定要在目标类型的范围内。
语法: 小范围类型 变量名称 = (小范围类型)大范围类型的值;
栗子
int a = 126;
byte b = 0;
b = (byte)a; //int型强转为byte型,正常
int c = 128;
System.out.println(b);//结果126
b = (byte)c; //int型强转为byte型,异常,精度丢失
System.out.println(b);//结果-128
这里需要说明的一点,当需要强转的值已经超出了要转类型的范围,会对要转值的补码进行截断,这也是为什么int类型128转为byte时值为-128的原因。至此,Java基本数据类型就算聊完了,由于引用数据类型是Java的核心,暂且先不做研究,后续会详细介绍的。下篇我们来细聊Java中的运算符。
更多最新技术文章,请关注“冰点IT”公众号