二、 变量、数据类型和运算符
2.1 变量
2.1.1 变量的声明
type varName [=value][,varName[=value]...];
//[ ]中的内容为可选项,即可有可无
数据类型 变量名[=初始值] [,变量名[=初始值]…];
2.1.2 变量的分类
- 局部变量:
- 成员变量(实例变量):
- 静态变量(类变量):
2.1.3 常量
常量的声明只需要在变量标识符前加"final"即可,只允许初始化一次。
final type varName [=value]
2.2 数据类型
Java是强类型语言,每种变量都要声明数据类型。
整数类型的占用存储空间分别为:byte-1字节;short-2字节;int-4字节;long-8字节。
浮点类型的占用存储空间分别为:float-4字节;double-8字节。
引用数据类型都是4字节,存放的是其引用对象的地址。
注:1字节(Byte) = 8 位 (bit)。
2.2.1 整型
Java默认的整型常量是int型,超过4字节(21亿)的数会报错,在数值后加字母"l"或"L"可声明为long型。
2.2.2 浮点型
浮点数不精确,比较的时候尽量不要使用浮点数。否则程序很可能会出现飘忽不定的Bug。
注意:java.math 包下面的两个有用的类:BigInteger 和BigDecimal,这两个类可以处理任意长度的数值。BigInteger 实现了任意精度的整数运算。BigDecimal 实现了任意精度的浮点运算。
Java默认浮点数是double型,想正确声明float型,可以在数值后加字母"F"。
public class float_test {
public static void main(String[] args){
// float a = 1.63; //会报错,a是double型的浮点数,不能赋值给float
float a = 1.63F; //想正确声明float型,可以在数值后加字母"F"
System.out.println(a);
float f1 = 0.1F;
double f2 = 1.0/10;
System.out.println(f2);
System.out.println(f1==f2); //f1和f2不相等,说明浮点型是不精确的
}
}
2.2.3 字符型
字符型占2字节存储空间。
2.2.4 布尔型
定义过程:
boolean b1 = ture;
boolean b2 = false;
通常与if条件判断语句结合起来。
2.2.5 数据类型转换
( 1 ) (1) (1) 自动类型提升
数据类型按容量从小到大排序:
byte /char /short < int < long < float < double
容量大的数据类型可以兼容容量小的。
特别的,当byte 、char 、short三种类型的变量做运算时,结果为int型。
( 2 ) (2) (2) 强制类型转换
①需要使用强制转换符:();
②可能会造成精度损失,从浮点型到整型时不遵循"四舍五入";
public class DataTypeTest {
public static void main(String[] args){
//强制类型转换测试
double d1 = 12.9;
int i1 = (int) d1; //截断操作,没有四舍五入
System.out.println(i1); //12
//没有精度损失
long l1 = 123;
short s1 = (short) l1;
System.out.println(s1); //123
//精度损失
int i2 = 128;
byte b1 = (byte) i2;
System.out.println(b1); //-128
}
}
2.3 运算符
2.3.1 算术运算符
long类型转到int类型的时候会报错,都会倾向于往兼容性更大的类型转变。如,如果是整型的话全部用long型为佳,小数浮点型用double为佳。
2.3.1.1 一元运算符
如i++,和i–,和++i与–i有什么区别呢?
具体的区别就是:例如
//自增和自减测试
int c = 1;
int c2 = c++;
System.out.println("The result of c++ is:"+c2);
System.out.println("The after c is:"+c);
int c3 = ++c;
System.out.println("The result of ++c is:"+c3);
System.out.println("The after c is:"+c);
上述代码的运行结果是:
The result of 10%4 is: 2
The result of 10÷3 is: 3
The result of double 10÷3 is: 3.3333333333333335
The result of c++ is:1
The after c is:2
The result of ++c is:3
The after c is:3
总结下来就是:
(1) 如果++在变量名后面,则先执行赋值操作,再进行自增;
(2) 如果++在变量名前面,则先执行自增,再进行赋值操作;
2.3.2 赋值运算符
2.3.3 关系运算符
关系运算符通常用于比较运算,主要在条件判断中比较常用。运算结果是布尔类型的值true 和 false。
注意:
(1) 字符类型char也可以用于关系运算符进行比较,因为char型的本质是Unicode编码,比较的时候就是比较编码值的大小。
例子如下:
//测试关系运算符
int d = 3;
int d2 = 5;
System.out.println(d>d2);
char d3 = 'a';
char d4 = 'b';
System.out.println("The Unicode of 'a' is:" + (int)d3);
System.out.println("The Unicode of 'b' is:" + (int)d4);
System.out.println(d4>d3);
System.out.println(d4>90);
运行的结果如下:
The Unicode of 'a' is:97
The Unicode of 'b' is:98
true
true
2.3.4 逻辑运算符
短路与和短路或采用短路的方式。从左到右计算,如果只通过运算符左边的操作数就能够确定该逻辑表达式的值,则不会继续计算运算符右边的操作数,提高效率。
//测试关系运算符
int d = 3;
int d2 = 5;
System.out.println(d>d2);
char d3 = 'a';
char d4 = 'b';
System.out.println("The Unicode of 'a' is:" + (int)d3);
System.out.println("The Unicode of 'b' is:" + (int)d4);
System.out.println(d4>d3);
System.out.println(d4>90);
//短路和,逻辑和的测试
boolean e1 = true;
boolean e2 = false;
System.out.println("The Logic AND is: " + (e1&e2));
System.out.println("The Logic OR is: " + (e1|e2));
System.out.println("The Logic NOT is: " + (!e1));
System.out.println("The Logic XOR is: " + (e1^e2));
//int e3 = 3 / 0; //0不能作除数,会报错
boolean e4 = 1>2 && (4<3/0);
System.out.println("The Short circuit AND is: " + (e4)); //这里的3/0没有报错,说明短路与直接跳过了&&右侧的运算
运行结果如下:
The Logic AND is: false
The Logic OR is: true
The Logic NOT is: false
The Logic XOR is: true
The Short circuit AND is: false
2.3.5 位运算符
例子代码如下:
//位运算符测试
int f1 = 1;
int f2 = 2;
System.out.println("The result of f1 & f2 is: " + (f1 & f2));
System.out.println("The result of f1 | f2 is: " + (f1|f2));
System.out.println("The result of f1 ^ f2 is: " + (f1^f2));
System.out.println("The result of ~f2 is: " + (~f2));
System.out.println("The result of 4<<f2 is: " + (4<<f2)); //4左移2位,相当于乘了2次2
System.out.println("The result of 4>>f2 is: " + (4>>f2)); //4右移2位,相当于除了2次2
运行结果如下:
The result of f1 & f2 is: 0
The result of f1 | f2 is: 3
The result of f1 ^ f2 is: 3
The result of ~f2 is: -3
The result of 4<<f2 is: 16
The result of 4>>f2 is: 1
2.3.6 字符串连接符
“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接。
注意:必须至少有一方时字符串类型,如果都是char型,用+号连接,会自动转化为Unicode编码的数字。但可以在输出中添加" ",转化为字符串操作。
例子代码:
int a =1;
System.out.println("The a is: " + a);
char c1 = 'a';
char c2 = 'b';
System.out.println(c1 + c2);
System.out.println("" + c1 + c5);
输出结果为:
The a is: 1
195
ab
2.3.7 条件运算符
① 使用格式:(条件表达式)?表达式1: 表达式2;
② 注意:表达式 1 和表达式 2 为 同种类型;
③ 三 元运算符与 if else 的联系与区别:
1)三元运算符可简化 if else 语句。
2)三元运算符要求必须返回一个结果。
3)if 后的代码块可有多个语句。
④代码例子:
public class TernaryOperator {
public static void main(String[] args){
//获取两个数的较大值
int i1 = 12;
int i2 = 14;
int max = i1 > i2? i1:i2;
System.out.println("The maximum is: "+ max); //The maximum is: 14
//遵循容量大的数据类型兼容容量小的原则
double max1 = i1 > i2? 8: 23.22;
System.out.println("The maximum is: " + max1); //The maximum is: 23.22
//字符串型必须表达式1和2都是才行
String max2 = i1 > i2? "i1大":"i2大";
System.out.println("The maximum is: " + max2); //The maximum is: i2大
//三元运算符可以嵌套使用
int i3 = 5;
int i4 = 5;
String max3 = i3 > i4? "i1大":(i3==i4? "i3等于i4": "i2大");
System.out.println("The maximum is: " + max3); //The maximum is: i3等于i4
//获取三个数的最大值(三元运算符的多重嵌套使用)
int a1 = 3;
int a2 = 5;
int a3 = 56;
//String max4 = a1 > a2? (a1 > a3? "最大值是a1=3" : "最大值是a3=56") : (a2 > a3? "最大值是a2=5": "最大值是a3=56"); //我写的,没必要这样写,可读性差很多
int max4 = a1 > a2? a1: a2;
int max5 = max4 > a3? max4: a3;
System.out.println("The maximum is: " + max5); //The maximum is: 56
}
}
⑤ 凡是可以用三元运算符的地方,都可以改写为if-else,反之则不行。如果两者都可以,则优先使用三元运算符,原因是简洁高效。
2.4 使用Scanner从键盘获取数据
2.4.1 获取int型数据
步骤 ( 1 ) (1) (1) 导入这个类的相关包:
import java.util.Scanner;
步骤 ( 2 ) (2) (2) Scanner 类的实例化
Scanner 对象名 = new Scanner(System.in);
步骤 ( 3 ) (3) (3) 调用Scanner类的相关方法,来获取指定的变量,除了String型和char型是.next( )外,其余都是.netXxx( ) 。
int 存储的变量名 = 对象名.nextInt();
代码例子:
import java.util.Scanner; //导入外部包
public class ScannerTest {
public static void main(String[] args){
System.out.print("Please input the number you want: ");
Scanner scan = new Scanner(System.in); //创建实例对象
int num = scan.nextInt(); //程序等待键盘输入
System.out.println("The number you input is: " + num);
}
}
输出结果:
Please input the number you want: 6
The number you input is: 6
2.4.2 获取其他类型数据
代码例子如下:
import java.util.Scanner; //导入外部包
public class ScannerTest {
public static void main(String[] args){
//获取String数据类型
System.out.print("Please input your name: ");
String name = scan.next();
System.out.println("Your name is: " + name);
//获取int数据类型
System.out.print("Please input your age: ");
int age = scan.nextInt();
System.out.println("Your age is: " + age);
//获取double数据类型
System.out.print("Please input your Weight: ");
double weight = scan.nextDouble();
System.out.println("Your weight is: " + weight);
//获取boolean数据类型
System.out.print("Do you like me? (true/false): ");
boolean like = scan.nextBoolean();
System.out.println("The fact of you like me is: " + like);
//获取char数据类型
System.out.print("Please input your gender: (男/女)");
String gender = scan.next();
char genderChar = gender.charAt(0); //查阅文档可知.charAt(0)是获取String型索引为第0个的字符
System.out.println("Your gender is: " + genderChar);
}
}
输出的结果:
Please input your name: 谢斯航
Your name is: 谢斯航
Please input your age: 23
Your age is: 23
Please input your Weight: 60.55
Your weight is: 60.55
Do you like me? (true/false): true
The fact of you like me is: true
Please input your gender: (男/女)男
Your gender is: 男
注意:
① Scanner类没有提供获取char型的方法。需要先通过String的.next( )获取字符串类型数据,再通过.charAt( ) 的方法获取指定索引的字符char。
② 如果Scanner 获取的数据类型不符合,可能会导致程序终止。
2.4.3 提取int型数字的每位数字的算法
算法 ( 1 ) (1) (1):
int num = 153;
int hundredth = num/100;
int decade = num%(hundredth*100)/10;
int bit = num%(hundredth*100 + decade*10);