1、数据类型概述
我们知道任何一个变量都包括三要素,分别是:数据类型、变量名、值。其中数据类型尤为重要,数据类型的作用就是决定程序运行阶段会给该变量分配多大的内存空间进行存储。Java数据类型包括两大类:基本数据类型和引用数据类型(之后学习)。引用数据类型又包括4类8大种:
第 1 类:整数型(不带小数的数字):byte,short,int,long
第 2 类:浮点型(带小数的数字):float,double
第 3 类:字符型(文字,单个字符):char
第 4 类:布尔型(真和假):boolean
计算机的容量单位换算:
1byte = 8bit(1 个字节是 8 个比特位)
1KB = 1024byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
2、字符编码
对于以上的八种基本数据类型来说,其中七种类型 byte,short,int,long,float,double,boolean
计算机表示起来是很容易的,因为这七种类型底层直接就是数字,十进制的数字和二进制之间 有固定的转换规则,所以计算机可直接表示和处理。但是大家别忘了,除了以上的七种数据类 型之外,还有一种类型叫做字符型 char,这个对于计算机来说表示起来就不是那么容易了,因 为字符毕竟是现实世界当中的文字,而文字每个国家又是不同的,计算机是如何表示文字的 呢?
实际上,起初的时候计算机只支持数字,因为计算机最初就是为了科学计算,随着计算机
的发展,为了让计算机起到更大的作用,因此我们需要让计算机支持现实世界当中的文字,一 些标准制定的协会就制定了字符编码(字符集),字符编码其实就是一张对照表,在这个对照 表上描述了某个文字与二进制之间的对应关系。
最初的时候美国标准协会制定了ASCII 码,ASCII(American Standard Code for Information
Interchange:美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现 代英语和其他西欧语言。它是现今最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。 ASCII 码采用 1 个字节编码,1个字节可以表示256种不同的形式(前面说过了),对于英文 来说这个足够了,因为英文单词就是由 26 个英文字母拼凑而成,大小写全部才52个,再加上 数字和标点符号也不会超过256 个。但ASCII 码对于中文来说那就不够了,因为汉字不止256 个。
常见的 ASCII 码需要大家能够记住几个,在 ASCII 码中规定’a’对应 97,'b’对应 98,以此
类推,'A’对应 65,'B’对应 66,以此类推,'0’字符对应48,‘1’字符对应49,以此类推,这些常 见的编码还是需要大家记住的。 在字符编码当中,有这样两个常见的术语需要大家了解一下:编码和解码,它们都是什么,我们拿字符’a’来解释一下:‘a’是 97,97 对应的二进制是01100001,那么从’a’到二进制01100001 的转换过程称为编码,从二进制 01100001 到’a’的转换过程称为解码。大家一定要注意:编码 和解码要采用同一种字符编码方式(要采用同一个对照表),不然会出现乱码。这也是乱码出 现的本质原因。 随着计算机的不断发展,为了让计算机支持更多国家的语言,国际标准组织又制定了ISO-8859-1字符集,又被称为latin-1,向上兼容ASCII码,仍不支持中文,主要支持西欧语言。 再后来,计算机慢慢的开始支持简体中文、繁体中文、日本语、朝鲜语等,其中支持简体中文 的字符集包括:GB2312 、GBK 、GB18030,它们的容量大小不同,其中GB2312 < GBK < GB18030。支持繁体中文的是大五码Big5等。后来,在上世纪90年代初,国际组织制定了一 种字符编码方式,叫做Unicode 编码,这种编码方式统一了全球所有国家的文字,具体的实现 包括:UTF-8,UTF-16,UTF-32 等。 Java为了国际化,为了支持所有国家的语言,所以 Java采用的编码方式为Unicode 编码。
例如字符’中’对应的 Unicode 码是’\u4e2d’。在实际开发中几乎所有的团队都会使用 Unicode 编 码方式,因为这种方式更通用,兼容性更好。 通过本小节的学习,大家需要理解字符编码是什么,有什么作用,常见的ASCII 码要知道
一些,另外要理解什么是编码,什么是解码,要知道编码和解码采用的字符编码方式不同时会 出现乱码,还要知道国际通用的编码方式为 ISO-8859-1,支持简体中文的编码方式包括 GB2312、GBK、GB18030,而 Java 采用 unicode 编码,目前在实际的开发中大部分团队都会 选择UTF-8 的编码方式。
3、数据类型详解
3.1字符型详解
字符型char占2个字节,char类型的字面量必须使用半角的单引号括起来,取值范围为[0-65535],char 和 short 都占用 2个字节,但是char 可以取到更大的正整数, 因为 char 类型没有负数’’。
public class CharTest01{
public static void main(String[] args){
char c = 'ab';
System.out.println(c);
}
}
以上代码会报这样的错误:“未结束的字符文字”,这是因为Java中有规定,字符型只能是单个字符,当编译器检测到’ab’的时候,左边以单引号开始,继续检测到 a 字符,然后编译器会继续检查下一个字符是否为另一半单引号,结果不是,而是b,所以编译 器报错了。这也说明了 Java中的字符只能是单个字符,不能是多个字符。
转义字符:转义字符指用一些普通的字符组合代表一些特殊的字符,由于组合用的字符改变了原意,称为转义字符。Java 中的转义字符以 \ 开始,常见的 转义字符有:\t、\n、\u、\、’,",其中\t 代表制表符,\n是换行符,\表示一个普通的\字符
3.2整数型详解
整数型数据在 java中有 4 种表示方式,分别是十进制、八进制、十六进制、二进制。Java默认为十 进制,以0开始表示八进制,以0x开始表示十六进制,以 0b开始表示二进制。
在 java 语言当中,整数型字面量被当做 int 类型处理,也就是说在程序中只要遇到整数型的数字,该数字会默认被当做 int类型来处理,如果想表示 long类型则需要在字面量后面添加 L/l,建议大写L,因为小写 l和 1 不好区分。
看以下代码
public class IntegerTypeTest02{
public static void main(String[] args{
int a = 10;
long b = 10L;
//10是int型字面量,却定义为long型,代码可以正常输出,
//这是因为 int 占用4 个字节,而long占用 8 个字节,在 Java中小容量可以 直接赋值给大容量,这个过程被称为自动类型转换。
long c = 10;
System.out.println(c);
//大容量赋值给小容量,必须强制类型转换。但有可能损失精度
int d = (int)c;
}
}
看以下代码
public class IntegerTypeTest05 {
public static void main(String[] args){
//以下代码编译报错:过大的整数2147483648,
//编译器默认将2147483648当作int类型,但超出了int类型的取值范围
long num = 2147483648;
//在2147483648后面加L可解决问题,加L告诉编译器是long类型的
long num = 2147483648L;
}
}
再看以下代码
public class IntegerTypeTest06 {
public static void main(String[] args) {
//1是int类型,占4个字节,byte占1个字节,大容量赋值给小容量,没有强制类型转换代码竟然运行成功
//这是因为在java语言有这样一条规定,如果当一个整数型字面量没有超出byte类型取值范围时,可以直接赋值给 byte 类型变量。
//如果超出,会报这样的错误:不兼容的类型,从int转换到byte可能会有损失。
byte b = 1;
System.out.println(b);
//类比char类型,同样的道理
char c1 = 97;
char c2 = 98;
System.out.println(c1);
System.out.println(c2);
}
}
3.3浮点型详解
浮点型数据实际上在内存中存储的时候大部分情况下都是存储了数据的近似值,这是因为在现实世界中存在无穷的数据,例如:3.333333333333333333…,数据是无穷的, 但是内存是有限的,所以只能存储近似值,float 单精度占4 个字节,double 双精度占8 个字节, 相对来说 double 精度要高一些。
在 java 语言中有这样的一条规定:只要是浮点型的字面量,例如1.0、3.14 等默认会被当做 double 类型来处理,如果想让程序将其当做 float 类型来处理,需要在字面量后面添加f/F。
3.4布尔型详解
Java中布尔型包括true和false,布尔类型的
数据在开发中主要使用在逻辑判断方面.
3.5基本数据类型转换
基本数据类型之间是存在固定的转换规则的,现总结出以下 6 条规则,无论是哪个程序,
将这 6 个规则套用进去,问题迎刃而解:
八种基本数据类型中,除 boolean类型不能转换,剩下七种类型之间都可以进行转换;
如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给 byte,short,char 类型的变量;
小容量向大容量转换称为自动类型转换,容量从小到大的排序为:byte < short(char) < int < long < float < double,其中 short 和 char 都占用两个字节,但是char 可以表示更大 的正整数;
大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但 运行时可能出现精度损失,谨慎使用;
byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;
public class TypeConversionTest {
public static void main(String[] args) {
//1000 超出 byte 取值范围,不能直接赋值
//byte b1 = 1000;
/** 如果想让上面程序编译通过,可以手动强制 * 类型转换,但程序运行时会损失精度 */
byte b1 = (byte)1000;
//20 没有超出 byte 取值范围,可以直接赋值 byte b2 = 20;
//1000 没有超出 short 取值范围,可以直接赋值 short s = 1000;
//1000 本身就是 int 类型,以下程序不存在类型转换 int c = 1000;
//小容量赋值给大容量属于自动类型转换
long d = c;
//大容量无法直接赋值给小容量
//int e = d;
//加强制类型转换符
int e = (int)d;
//int 类型和 int 类型相除最后还是int类型,所以结果是 3 int f = 10 / 3;
long g = 10;
/**g是 long类型,long类型和int类型最终结果是long类
* 型,无法赋值给 int 类型
* */
//int h = g / 3;
//添加强制类型转换符 int h = (int)(g / 3);
//long类型赋值给 long类型 long m = g / 3;
/** g先转换成 byte,byte 和 int 运算,最后是 int 类型,
* 无法直接赋值给 byte
**/
//byte x = (byte)g / 3;
//将以上程序的优先级修改一下 byte x = (byte)(g / 3);
short y = (short)(g / 3);
short i = 10;
byte j = 5;
/** short 和 byte 运算时先各自转换成 int 再做运算,结
* 果是 int 类型,无法赋值给 short
**/
short k = i + j;
int n = i + j;
char cc = 'a';
System.out.println("cc = " + cc);
//将字符型 char 转换成数字,'a'对应的ASCII 是 97 System.out.println((byte)cc);
/** char 类型和 int 类型混合运算,char 类型先转换成
* int 再做运算,最终 197
**/
int o = cc + 100;
System.out.println(o);
}
}
总结
通过本章节内容的学习,需要理解数据类型在程序中的作用,需要掌握在 Java语言中数据 类型包括哪些,其中基本数据类型又包括哪些,每个基本数据类型所占用的字节数量,byte 类型取值范围等。另外需要理解字符编码在程序中的作用。还有每一种数据类型特有的语法机 制,包括整数型字面值默认当做 int 类型处理,如果以long形式表示,需要在字面值后添加L,或 l;浮点型字面量默认被当做 double 处理,后面添加 F/f才可以被当做 float 类型;而布尔型 在 Java中只有 true 和false 没有其他值;字符型变量完全可以存储1 个汉字等。还有基本数据类型之间的转换