JavaSE基础 第四章 数据类型
文章目录
1. 数据类型概述
- 作用 : 用来声明变量, 不同的数据类型分配不同的大小空间.
- 分类 :
- 基本数据类型 ( 4大类8小种 ) :
- 整数型 ( byte, short, int, long )
- 浮点型 ( float, double )
- 布尔型 ( boolean )
- 字符型 ( char )
- 引用数据类型 :
- 字符串( String )
- java中除了基本数据类型外, 剩下的都是引用数据类型.
- 引用数据类型后期讲的面向对象会接触.
- 基本数据类型 ( 4大类8小种 ) :
- 计算机存储单位 :
单位 | 描述 |
---|---|
bit (比特位) | 1bit表示一个1或0, 计算机是将接收到的信息转化成能识别的二进制码 |
byte (字节) | 1字节=8bit |
kb | 1kb=1024byte |
mb | 1mb=1024kb |
gb | 1gb=1024mb |
tb | 1tb=1024gb |
类型 | 占用字节数量 |
---|---|
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
boolean | 1 |
char | 2 |
- 进制转换
- 二, 八, 十六进制 转 十进制 :
- 十进制 转 二, 八, 十六进制 :
- 二, 八, 十六进制 转 十进制 :
- 取值范围 :
数据类型 | 取值范围 | 默认值 |
---|---|---|
byte | -128 ~ 127 | 0 |
short | -32768 ~ 32767 | 0 |
int | -2147483648 ~ 2147483647 | |
long | \ | 0L |
float | \ | 0.0f |
double | \ | 0.0 |
boolean | true, false | false |
char | 0 ~ 65535 | ‘\u0000’ |
byte类型的取值范围 :
[-128 ~ 127], 可以标识256个不同的数字
byte类型的最大值 :
byte是1个字节, 8个比特位, 所以byte可以存储的最大值为 : 01111111
注意 : 计算机中, 一个二进制位最左边的是符号位, 0表示正数, 1为负数short和char实际上容量相同 ( 65536 ), 不过char可以表示更大的数字, 因为char表示的是文字, 没用正负之分.
2. 字符编码
- 特殊的char :
其中byte, short, int, long, float, double, boolean这7种类型, 计算机表示起来标胶容易, 因为他们都是数字. 其中boolean只有两个值true和false, 实际上在C++中, true为1, false为0.
而对于char类型来说, 计算机表示起来比较麻烦, 因为char对应的是文字, 每个国家的文字都是不同的, 文字直接不能通过 “自然算法” 转换成二进制. 这个时候字符编码就诞生了.
- 字符编码 :
字符编码是人为定义 ( 某个计算机协会规定的 ) 的一套转换表.
实质上是一本字典, 规定了一系列文字对应的二进制.
字符编码涉及到编码和解码两个过程, 编码和解码的时候必须采用同一套字符编码方式, 否则会出现乱码.
字符编码的发展过程 :
起初计算机是不支持文字的, 只支持科学计算, 实际上计算机是为了战争而开发的.
随着计算机的发展, 计算机开始支持文字, 最先支持的是英文, 英文对应的字符编码是 ASCII码.
ASCII码采用1byte进行存储, 因为英文字母是26个. ( 键盘上所有的键加起来也超不过256个, 1byte可以表示256中不同的情况, 所以英文本身在计算机方面就占有一定的优势. )
-------------------------------------------------------------------------------------------------------------------
‘a’ — ( 采用ASCII码进行编码 ) -> 01100001
01100001 — ( 采用ASCII码进行解码 ) -> ‘a’
‘a’ ----> 97
‘b’ ----> 98
‘c’ ----> 99
…
‘A’ ----> 65
‘B’ ----> 66
…
‘0’ ----> 48 ( 这个’0’是字符0 )
‘1’ ----> 49
…又随着计算机的发展, 国际组织制定了ISO-8856-1编码方式, 又称为latin-1编码方式, 向上兼容ASCII码, 但不支持中文.
后来发展到亚洲, 才支持中文, 日文…
中文的编码方式 : GB2312 < GBK < GB18030 ( 容量的关系 )
以上编码的方式为简体中文.繁体中文 : Big5
java为了支持全球所有的文字, 采用了一种字符编码方式叫做Unicode编码, 具体的实现包括 : UTF-8, UTF-16, UTF-32…
3. 数据类型详解
字符char
- char可以容纳一个汉字
- 转义字符 :
常用转义字符 | 表示 |
---|---|
\n | 换行 |
\t | 制表符, 注 : 字符串长度为1 |
\' | 用于表示字符常量’ |
\" | 用于表示一个字符串内部的双引号 |
\\ | 用于表示一个反斜杠,防止它被解释为一个转义符 |
\ddd | ddd表示1~3个八进制的数字. 如 : \101表示A, 字符串长度为1 |
\u十六进制数 | \u后面的是一个字符unicode编码, 表示一个字符 |
\xdd | dd表示2个十六进制数字. 如:\x61表示a, 字符串长度为1 |
不常用转义符 | 表示 |
---|---|
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\r | 回车 |
\v | 垂直制表符 |
- print和println
整数型byte, short, int long
-
默认int
对于整数型来说, 最常用的是int.
实际开发时, 直接使用int即可, 如果有特殊要求, 使用其他的 -
自动类型转换
- 在任何情况下, 整数型的’字面量’默认被当作int类型来处理.
- 如果希望该’整数型字面量’被当作long类型来处理, 需要在’字面量’后面添加L
建议使用大写L, 因为小写l和1傻傻分不清.
public class IntTest02{
public static void main(String[] args){
// 不存在类型转换
int a = 100;
System.out.println(a);
// 存在类型转换, 因为200这个字面量默认被当作int类型来处理
// b变量是long类型, int是4个字节, long是8个字节
// 小容量可以自动转换成大容量, 这种操作叫做 : 自动类型转换
long b = 200;
System.out.println(b);
// 不存在类型转换, 因为字面量300L是long类型
long c = 300L;
System.out.println(c);
// 题目:
// 可以吗? 存在类型转换吗?
// 可以, 而且存在类型转换
long d = 2147483647;
System.out.println(d);
// 错误 : 整数太大
// long e = 2147483648;
// 这样就不会报错了, 字面量2147483648L被当作long类型来处理
long e = 2147483648L;
System.out.println(e);
}
}
- 强制类型转换
- 自动类型转换 : 小容量转换成大容量
- 强制类型转换 : 大容量不能直接转换成小容量, 需要使用强制类型转换符进行强转.
但需要注意的是: 加上强制类型转换符后, 虽然编译通过了, 但是运行的时候可能会损失精度(超出小容量的范围时).
public class IntTest03{
public static void main(String[] args){
long x = 100L;
// int y = x;
// 底层是如何进行强转的呢?
// long类型的100L: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100100
// 以上是long类型的100L强转为int, 会自动将前面4( long8 - int4 )个字节砍掉
// 剩下 : 00000000 00000000 00000000 01100100 , 因为值小, 所以不会损失精度
int y = (int)x; // (int)强制类型转换符
System.out.println(y);
}
}
- 精度损失
public class IntTest04{
public static void main(String[] args){
// int300 : 00000000 00000000 00000001 00101100
// 强转后 : 会砍掉3( int4 - byte1 )个字节, 最后的结果为: 00101100, 十进制为44, 精度损失256
byte b = (byte)300;
System.out.println(b); // 44
}
}
- 特殊byte, short和char
当一个整数型字面量没有超出byte或short或char的取值范围,那么这个整数型字面量可以直接赋值给byte或short或char类型的变量, long是不行的. 这种语法机制是为了方便写代码而存在的.
public class IntTest05{
public static void main(String[] args){
byte x = 1;
byte y = 127;
// 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte z = 128;
short a = 1;
short b = 32767;
// 错误: 不兼容的类型: 从int转换到short可能会有损失
short c = 32768;
char c1 = 'a';
char c2 = 97;
char c3 = 65535;
// 错误: 不兼容的类型: 从int转换到char可能会有损失
char c4 = (char)65536;
System.out.println(c4);
}
}
- 二进制原码, 反码, 补码
- 计算机在任何情况下, 都只能识别二进制
- 计算机在底层存储数据时, 一律存储的是二进制的补码形式**( 补码形式效率最高 ), 打印的是原码**
- 补码 :
二进制有 : 原码, 反码, 补码 - 对于一个正数来说 : 二进制原码, 反码, 补码都相同
对于一个负数来说 :
byte b = -1;
对应的原码 : 10000001
反码 : 11111110 ( 符号位不变, 其他位取反 )
补码 : 11111111 ( 反码+1 )
public class IntTest06{
public static void main(String[] args){
// 00000000 00000000 00000000 10010110
// 补码 : 10010110
// 反码 : 10010101
// 原码 : 11101010 , -106
byte b = (byte)150;
System.out.println(b); // -106
}
}
- byte, short, char的混合运算
byte, short, char做混合运算时, 各自先转换成int再做运算
public class IntTest07{
public static void main(String[] args){
char c1 = 'a';
byte b = 1;
// 注意 : 这里的+是负责求和的
System.out.println(c1 + b);
// 错误: 不兼容的类型: 从int转换到short可能会有损失
short a = c1 + b; // 而这样写到这里不知道这个加法最后的结果是多少, 只知道是int类型
short s = 98; // 98直接写到这里编译器可以识别
System.out.println(s);
}
}
- 多类型的混合运算
多种数据类型做混合运算时, 最终的结果类型是"最大容量"对应的类型
char + short + byte这个除外
因为char + short + byte混合运算时, 会各自先转换成int再做运算
public class IntTest08{
public static void main(String[] args){
long a = 10L;
char c = 'a';
short s = 100;
int i = 30;
// 求和
System.out.println(a + c + s + i); // 237
// 计算结果是long类型
int x = (int)(a + c + s + i);
System.out.println(x);
}
}
浮点型float, double
-
浮点型包括:
float : 4个字节, 单精度
double : 8个字节, 双精度, 更精确 -
但是需要注意的是, 如果在银行方面或者财务方面, double时远远不够的, 在Java中提供了一种精度更到的类型,
这种类型专门使用在财务软件方面 : java.math.BigDecimal ( 引用数据类型 ) -
float和double存储数据时都是存储的近似值, 因为现实世界中有这种无限循环数据, 但是计算机的内存有限,
用一个有限的资源存放无限的数据只能使用近似值. -
注意 : 任意一个浮点型都比整数型空间大
float容量 > long容量 -
规定 : 任意一个浮点型数据默认被当作double来处理, 如果想让这个浮点型数据被当作float来处理, 那么请在数据
后面添加F/f.
public class FloatTest01{
public static void main(String[] args){
// 不存在类型转换
double pai = 3.1415926;
System.out.println(pai);
//
float pi = 3.14F;
System.out.println(pi);
int i = (int)(10.0 / 5);
System.out.println(i);
}
}
布尔型boolean
- 布尔类型只有true和false两个值
- boolean在实际开发中使用在逻辑判断中, 通常放在条件的位置
public class BooleanTest01{
public static void main(String[] args){
// 错误: 不兼容的类型: int无法转换为boolean
// boolean xingBie = 1;
// System.out.println(xingBie);
boolean sex = false;
if (sex){
System.out.println("男");
}else {
System.out.println("女");
}
int a = 1;
int b = 2;
boolean flag = (a < b);
System.out.println(flag);
}
}
4. 基本数据类型转换
-
八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以进行转换;
-
如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋值给byte,short,char 类型的变量;
-
小容量向大容量转换称为自动类型转换,容量从小到大的排序为:byte < short(char) < int < long < float < double,其中
short 和 char 都占用两个字节,但是 char 可以表示更大的正整数; -
大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,但运行时可能出现精度损失,谨慎使用;
-
byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
-
多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;
5. 本章习题
第一题:
1. short s1 = 1; s1 = s1 + 1;有什么错?
2. char 类型变量能不能储存一个中文的汉字,为什么?
3. float f = 1.0 有什么错?
4. long a = 2147483648 有什么错?
5. int i = 0xffff 有问题吗?
6. char c = 65536 有问题吗,为什么?
第二题:
接下来,根据以上的 6 条规则,我们来看一下以下代码,指出哪些代码编译报错,以及怎么解决(大家注意看代码的注释信息):
byte b1 = 1000;
byte b2 = 20;
short s = 1000;
int c = 1000;
long d = c;
int e = d;
int f = 10 / 3;
long g = 10;
int h = g / 3;
long m = g / 3;
byte x = (byte)g / 3;
short y = (short)(g / 3);
short i = 10;
byte j = 5;
short k = i + j;
int n = i + j;
char cc = 'a';
System.out.println("cc = " + cc);
System.out.println((byte)cc);
int o = cc + 100;
System.out.println(o);
6. 习题答案
第一题:
public class DataTest{
public static void main(String[] args){
// 1. short s1 = 1;
// 错误: 不兼容的类型: 从int转换到short可能会有损失
// s1 = s1 + 1;
// 2. char c1 = '中';
// 3. float f = (float)1.0;
// float f = 1.0F;
// 4. 错误: 整数太大
// long a = 2147483648;
// 改正
// long a = 2147483648F;
// 5. D:\Java\Java_code\chapter04>javac DataTest.java
// D:\Java\Java_code\chapter04>java DataTest
// 65535
// int i = 0xffff;
// 6. 错误: 不兼容的类型: 从int转换到char可能会有损失
// char c = 65536;
System.out.println(s1);
}
}
第二题:
public class TypeConversionTest{
public static void main(String[] args){
// 1.
byte b2 = 20;
// 2.
short s = 1000;
// 3.
int c = 1000;
// 4.
long d = c;
// 5. 错误: 不兼容的类型: 从long转换到int可能会有损失
// int e = d;
// 原因: c是int类型, 小容量转大容量( 自动类型转换 ), 先将类型转换成long, 再赋值给d, 此时d是long类型,
// 大容量转小容量( 强制类型转换 ), 应使用强制类型转换符.
// 6.
int f = 10 / 3;
// 7.
long g = 10;
// 8. 错误: 不兼容的类型: 从long转换到int可能会有损失
// int h = g / 3;
// 原因: g是int类型, 小容量转大容量( 自动类型转换 ), 先将类型转换成long, 再赋值给h, 此时h是long类型,
// 大容量转小容量( 强制类型转换 ), 应使用强制类型转换符.
// 9.
long m = g / 3;
// 10. 错误: 不兼容的类型: 从int转换到byte可能会有损失
// byte x = (byte)g / 3;
// 原因: (byte)g强转成byte类型, 它/3运用了多类型运算规则, 即多类型运算时, 应该将所有的转换成最大的那个类型,
// 再进行运算, 这是(byte)g / 3就是int类型了, 自然就不能赋值给byte类型的x.
// 11.
short y = (short)(g / 3);
// 12.
short i = 10;
// 13.
byte j = 5;
// 14. 错误: 不兼容的类型: 从int转换到short可能会有损失
// short k = i + j;
// 原因 : i和j都是强转成的int, 只不过将强转负号隐藏了, 所以i + j后还是int, 不能直接赋值给short类型的k.
// 15.
int n = i + j;
// 16.
char cc = 'a';
// cc = a
System.out.println("cc = " + cc);
// 17. 输出97
System.out.println((byte)cc);
// 18. 输出197
int o = cc + 100;
System.out.println(o);
}
}