初级03 - Java的数据类型
2019-07-24 本文已影响0人
晓风残月1994
在开始写程序之前,我们必须知道程序将操作什么样的数据。
- 二进制与字节
- 原生数据类型
- 引用数据类型
- 自动装箱/拆箱机制
1. 基本数据类型
整型:
- byte - 1个字节 2^7 ~ -2^7-1
- short - 2个字节
- int - 4个字节 2^31 ~ -2^31-1 (int 很常用,注意取值范围大概±21亿,不要overflow)
- long - 8个字节 2^63 ~ -2^63-1
- char - 2个字节
浮点型:
- float - 4个字节
- double - 8个字节
浮点型是近似的表达法,所以判断浮点数相等时,不要直接比较相等,但可以比较大小,推荐这样:
double d = doCalculate();
if (Math.abs(d - 2.0) < 0.000001) {
// 此时可以认为浮点数 d 和 2.0 相等
}
- boolean - true/false
- void?
声明基本数据类型:
// 字面量
long number = 1L;
float number = 1f;
double number = 1d;
int number = 0x7fffffff; // 也可以使用其他进制,等价于 2147483647,但更好记忆
long maxLong = 0x7fffffffffffffffL;
2. 类型转换与类型提升
- 整数除法是地板除
- 将所有类型提升到最高精度进行计算
- 丢失精度时需要进行强制转换
public class Main {
public static void main(String[] args) {
System.out.println(divide(3, 2));
}
public static double divide(int a, int b) {
// int result = a / b; // 地板除,答案是 1.0
double result = (double) a / b; // 强制转换
// double result = 1.0 * a / b; // 或者这样来被动提升大家的逼格
return result;
}
}
注意 char 字符类型的,代表的是码表中的字符(单个)
public class Main {
public static void main(String[] args) {
char c = '1';
// 字符 '1' 对应的 ASCII 码是 49,所以以下完全等价
char c = 49;
// c = c + 1; // 这样会报错,char + int 计算时,char 会提升逼格到 int 来进行计算,而 c 已经是 char 了,不能再这样赋值
c = (char) (c + 1); // c 变为 int 49 先和 int 1 参与计算,再把 50 强制类型转换为 char,所以结果就是 '2';
System.out.println(divide(3, 2));
}
}
类型转换的例子:
package com.github.hcsp.datatype;
public class Cast {
// Cast an int to byte
// 将int类型转换成byte
public static byte int2byte(int i) {
return (byte) i;
}
// Cast an int to short
// 将int类型转换成short
public static short int2short(int i) {
return (short) i;
}
// Cast an int to char
// 将int类型转换成char
public static char int2char(int i) {
return (char) i;
}
// Cast an int to String, e.g. 123 -> "123"
// 将一个整数转换为字符串,例如,将123转换成字符串"123"
public static String int2String(int i) {
return Integer.toString(i);
// return String.valueOf(i);
// return i + "";
}
// Cast an String to int, e.g. "123" -> 123
// 将一个字符串转换成整数,例如,将字符串"123"转换成整数123
public static int string2int(String s) {
return Integer.parseInt(s);
// return Integer.valueOf(s);
}
// Cast an String to double, e.g. "1.23" -> 1.23
// 将一个字符串转换成double类型,例如,将字符串"1.23"转换成1.23
public static double string2double(String s) {
return Double.parseDouble(s);
// return Double.valueOf(s);
}
// Cast an Long to int
// 将Long类型转换成int
public static int Long2int(Long l) {
return l.intValue();
// return Integer.parseInt(l.toString());
}
// Cast an Double to long
// 将Double类型转换成long
public static long double2Long(Double d) {
return d.longValue();
// return Math.round(d);
}
}
3. 基本数据类型对应的装箱类型
- Byte
- Short
- Integer
- Long
- Float
- Double
- Character
- Boolean
Void?
为什么需要装箱类呢?
- 容器类不接受原生数据类型
- 可以赋值为 null
- 提供额外的方法
- 自动装箱与拆箱
但有坑点:
- 对 null 自动拆箱会已发空指针异常
- == 和 equals 约定(相同 vs 相等)
原生数据类型可用 == 判断,而装箱类型是对象,对象是对存储地址的引用,除非引用同一个对象地址,才是相同。但可用 equals 判断实际堆中的值是否相等。
// 在 1 byte 的取值范围内时,会被 IntegerCache 缓存,用于节省细碎的装箱对象,所以 a 和 b 存储的对象地址是相同的
Integer a = 127;
Integer b = 127;
if (a == b) {
System.out.println("a == b"); // a == b
}
// 当超出 1 byte 的取值范围后,则 a 和 b 存储的是两个不同的对象地址
Integer a = 127;
Integer b = 127;
if (a == b) { // 并不相同
System.out.println("a != b");
}
if (a.equals(b)) { // 但是相等
System.out.println("a equals b!"); // a equals b!
}