变量与类型
字面常量的分类:
字符串常量:由“”括起来的,eg:“123”,“hello”
整形常量:程序中经常出现的数字:100,50等
浮点数常量:程序中经常出现的小数:3.14等
字符常量:由‘’括起来的单个字符:‘a’,‘3’
布尔常量:只有TRUE和FALSE
空常量:null
数据类型

这是八种基本的数据类型,除此之外,还有一些引用数据类型:数组、String、类、接口、枚举......
包装类:每个基本数据类型都会对应一个个类类型,这个类类型就是包装类,简单来说,包装类是基本类型的plus版本。
除了int类型与char类型,其他类型的包装类都是开头字母大写,而int类型包装类是Integer,char类型的包装类是Character。
1.1整型变量
public class Main {
public static void main(String[] args) {
int a = 10;
System.out.println(a);
}
}
这是一个最简单的int类型变量,运行结果为10。值得注意的是,我们在编写程序时变量必须要初始化,如果不初始化则不会通过编译。
在java中,一个int类型变量占4个字节,和操作系统没有直接的关系。而4个字节的表示范围是-2^31—2^31-1,如果超出了int类型变量的范围则会报错。如果int类型不够的话,java编译器给我们提供了long类型。
1.2长整型变量
public class Main {
public static void main(String[] args) {
long a = 10L;
System.out.println(a);
}
}
运行结果依然是10,但我们注意到我们在10的后面加上了L,是因为java是一个强语言类型的编程语言,如果我们去掉L,则会编译器报错。
一个long类型的变量占8个字节,所以long类型的取值范围是-2^63—2^63-1。
1.3单精度浮点型变量
public class Main {
public static void main(String[] args) {
float a = 10f;
System.out.println(a);
}
}
在工作中我们一般使用双精度浮点类型比较多。
1.4双精度浮点数
我们先来看一段神奇的代码
public class Main {
public static void main(String[] args) {
int a = 1;
int b = 2;
int num = a/b;
System.out.println(num);
}
}

运行结果为0,这是因为1/2是小数,我们需要更加精确的浮点类型。
所以我们要修改代码
public class Main {
public static void main(String[] args) {
double a = 1.0;
double b = 2.0;
double num = a/b;
System.out.println(num);
}
}

这样才能得出正确答案。
1.5字符类型常量
字符类型也是一个比较常见的变量类型,我们可以用其输出字符和汉字。
public class Main {
public static void main(String[] args) {
char a = 'A';
System.out.println(a);
}
}

1.6字节类型变量
字节类型变量只占一个字节,在程序编译时多要进行类型提升。
public class Main {
public static void main(String[] args) {
byte value = 0;
System.out.println(value);
}
}

1.7 短整型变量
public class Main {
public static void main(String[] args) {
short value = 0;
System.out.println(value);
}
}
1.8布尔类型变量
public class Main {
public static void main(String[] args) {
boolean value = true;
System.out.println(value);
}
}

1.9字符类型变量
public class Main {
public static void main(String[] args) {
String name = "zhangsan";
System.out.println(name);
}
}

除此之外,还有需要注意的是字符串类型的+号是拼接的意思
public class Main {
public static void main(String[] args) {
String a = "hello";
String b = "world";
System.out.println(a+b);
}
}

public class Main {
public static void main(String[] args) {
String a = "10";
String b = "20";
System.out.println("a = "+a+"b = "+b);
}
}

字符串后跟+都是拼接的意思。
1.10变量的作用域
一般变量的作用域都是变量所在的大括号里,若超出大括号则编译失败。
class Test {
public static void main(String[] args) {
{
int x = 10;
System.out.println(x); // 编译通过;
}
System.out.println(x); // 编译失败, 找不到变量 x.
}
}
1.11理解变量转换
int a = 10;
long b = 20;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.
int a = 10;
double b = 1.0;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.
long 表示的范围更大, 可以将 int 赋值给 long, 但是不能将 long 赋值给 int. double 表示的范围更大, 可以将 int 赋值给 double, 但是不能将 double 赋值给 int. 结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行.
int a = 10;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = b; // 编译出错, 提示不兼容的类型
int 和 boolean 是毫不相干的两种类型, 不能相互赋值.
byte a = 100; // 编译通过
byte b = 256; // 编译报错, 提示 从int转换到byte可能会有损失
注意: byte 表示的数据范围是 -128 -> +127, 256 已经超过范围, 而 100 还在范围之内.
int a = 0;
double b = 10.5;
a = (int)b;
int a = 10;
boolean b = false;
b = (boolean)a; // 编译出错, 提示不兼容的类型.
1. 强制类型转换可能会导致精度丢失. 如刚才的例子中, 赋值之后, 10.5 就变成 10 了, 小数点后面的部分被忽略. 2. 强制类型转换不是一定能成功, 互不相干的类型之间无法强转.
类型转换小结 1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型. 2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失. 3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查.
1.12数值提升
int a = 10;
long b = 20;
int c = a + b; // 编译出错, 提示将 long 转成 int 会丢失精度
long d = a + b; // 编译通过
当 int 和 long 混合运算的时候, int 会提升成 long, 得到的结果仍然是 long 类型, 需要使用 long 类型的变量来 接收结果. 如果非要用 int 来接收结果, 就需要使用强制类型转换
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 编译报错
Test.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失
byte c = a + b;
^
byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a + b 会先将 a 和 b 都 提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误.
类型提升小结: 1. 不同类型的数据混合运算, 范围小的会提升成范围大的. 2. 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算.