7.4 整数能否直接赋值给char
- 当一个整数赋值给char类型变量的时候,会自动转换成char字符型,最终的结果是一个字符。
- 当一个整数没有超出byte、short、char的取值范围的时候,这个整数可以直接赋值给byte short char类型的变量。
public class CharTest03{
public static void main(String[] args){
// 这里会做类型转换吗?
// 97是int类型(这是java中规定,默认当做int处理)
// c2是char类型
//char c2 = (char)97; // 不需要这样做。
char c2 = 97;
System.out.println(c2); // 'a'
// char类型取值范围:[0~65535]
char c3 = 65535; // 实际上最终是一个“看不懂”的字符。
System.out.println(c3);
//错误: 不兼容的类型: 从int转换到char可能会有损失
//char c4 = 65536;
// 怎么解决以上问题?
char c4 = (char)65536;
byte x = 1;
short s = 1;
char c = 1;
}
}
7.5 原码 反码 补码
- 对于一个正数来说:二进制原码、反码、补码是同一个,完全相同。
int i = 1;<br /> 对应的二进制原码:00000000 00000000 00000000 00000001<br /> 对应的二进制反码:00000000 00000000 00000000 00000001<br /> 对应的二进制补码:00000000 00000000 00000000 00000001
- 对于一个负数来说:二进制原码、反码、补码是什么关系呢?
byte i = -1;<br /> 对应的二进制原码:10000001<br /> 对应的二进制反码(符号位不变,其它位取反):11111110<br /> 对应的二进制补码(反码+1):11111111<br /> 我们以:byte b = (byte)150; 这条语句为例<br /> 这个b是多少?<br /> int类型的4个字节的150的二进制码是什么?<br /> 00000000 00000000 00000000 10010110<br /> 将以上的int类型强制类型转为1个字节的byte,最终在计算机中的二进制码是:10010110<br /> 千万要注意:计算机永远存储的都是二进制补码形式。也就是说上面<br /> 10010110 这个是一个二进制补码形式,你可以采用逆推导的方式推算出<br /> 这个二进制补码对应的原码是啥!!!!!!<br /> 10010110 ---> 二进制补码形式<br /> 10010101 ---> 二进制反码形式<br /> 11101010 ---> 二进制原码形式
这里我们需要注意一下,可能会有疑问的是,150不是正数吗。为啥还要这样,这是因为150做了一一强制转换,我们可以看成他的补码其实是10010110,第一位是符号位,是1,则为负数。
public class IntTest05{
public static void main(String[] args){
// 编译报错:因为150已经超出了byte取值范围,不能直接赋值,需要强转
//byte b = 150;
byte b = (byte)150;
// 这个结果会输出多少呢?
System.out.println(b); // -106
}
}
7.6 byte、char、short做混合运算
- byte、char、short做混合运算的时候,各自先转换成int再做运算。
public class IntTest06{
public static void main(String[] args){
char c1 = 'a';
byte b = 1;
// 注意:这里的"+"是负责求和的
System.out.println(c1 + b); // 98
// 错误: 不兼容的类型: 从int转换到short可能会有损失
//short s = c1 + b; // 编译器不知道这个加法最后的结果是多少。只知道是int类型。
// 修改
short s = (short)(c1 + b);
int a = 1;
short x = 1; 可以
short x = a; // 不可以,编译器只知道a是int类型,不知道a中存储的是哪个值。
System.out.println(x);
char cc = 'a';
// cc 会先自动转换成int类型,再做运算
int o = cc + 100;//cc==97
System.out.println(o); // 197
}
}
7.7 多种数据类型做混合运算
- 多种数据类型做混合运算的时候,最终的结果类型是“最大容量”对应的类型。char+short+byte 这个除外(char + short + byte混合运算的时候,会各自先转换成int再做运算)。
public class IntTest07{
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可能会有损失
// 计算结果是long类型
//int x = a + c + s + i;
//修改
int x = (int)(a + c + s + i);
System.out.println(x);
}
}
8. 浮点型
- 浮点型包括float(单精度)占4字节,double(双精度)占8字节;
- 需要注意的是,如果用在银行方面或者说使用在财务方面,double也是远远不够的,在java中提供了一种精度更高的类型,这种类型专门使用在财务软件方面:java.math.BigDecimal (不是基本数据类型,属于引用数据类型。)
- float和double存储数据的时候都是存储的近似值。
- 任意一个浮点型都比整数型空间大。虽然long类型占用8个字节,float类型占用4个字节,但是float容量 > long容量,我们也可以认为浮点型的精度更高,整型与浮点型比较的是精度,而不是所占字节大小。
java中规定,任何一个浮点型数据默认被当做double来处理。如果想让这个浮点型字面量被当做float类型来处理,那么请在字面量后面添加F/f。
public class FloatTest01{
public static void main(String[] args){
// 分析这个程序,可以编译通过吗?
// 错误: 不兼容的类型: 从double转换到int可能会有损失
// 原理:先将5转换成double类型,然后再做运算,结果是double
// 大容量无法直接赋值给小容量,需要强转。
//int i = 10.0 / 5;
// 怎么修改
int i = (int)10.0 / 5;
System.out.println(i); // 2
// 可以这样修改吗?强转的时候只留下整数位。
int x = (int)(10.0 / 5);
System.out.println(x); // 2
}
}
9. 布尔类型
- 在java语言中boolean类型只有两个值,true和false;不像C或者C++,C语言中1和0也可以表示布尔类型。
- 布尔类型不可以和其它基本数据类型发生转换
第五章 运算符
1. 运算符概述
1.1 算术运算符
- 算术运算符有:+、-、*、/、%、++、--
- 我们主要说明一下自增自减,以自增为例(自减和自增差不多,可参考自增)
可以出现在变量前,也可以出现在变量后,不管出现在变量前还是后,总之++执行结束之后,变量的值一定会自加1。
public class OperatorTest01{
public static void main(String[] rags){
int a = 10;
int b = 3;
System.out.println(a + b); // 13
System.out.println(a - b); // 7
System.out.println(a * b); // 30
System.out.println(a / b); // 3
System.out.println(a % b); // 1
// 重点掌握 ++ 和 --
// 这里重点讲解 ++,至于-- 大家可以照葫芦画瓢。
// ++ 自加1(++可以出现在变量前,也可以出现在变量后。)
int i = 10;
// i变量自加1
i++;
System.out.println(i); //11
int k = 10;
// k变量自加1
++k;
System.out.println(k); //11
// 研究:++出现在变量前和变量后有什么区别?
// 先看++出现在变量后。
// 语法:当++出现在变量后,会先做赋值运算,再自加1
int m = 20;
int n = m++;
System.out.println(n); // 20
System.out.println(m); // 21
// ++出现在变量前呢?
// 语法规则:当++出现在变量前的时候,会先进行自加1的运算,然后再赋值。
int x = 100;
int y = ++x;
System.out.println(x); // 101
System.out.println(y); // 101
// 题目
int c = 90;
System.out.println(c++); // 传,这个“传”在这里有一个隐形的赋值运算。90
// 把上面代码拆解开
//int temp = c++;
//System.out.println(temp);
System.out.println(c); // 91
int d = 80;
System.out.println(++d); //81
// 拆解
//int temp2 = ++d;
//System.out.println(temp2);
System.out.println(d); // 81
/*
int e = 1;
int f = e; // e赋值给f,表示将e“传”给了f
*/
}
}
1.2 关系运算符
- 关系运算符有:>、>、= 、< 、<= 、==、 !=
- 所有的关系运算符的运算结果都是布尔类型
- 关系运算符中如果有两个符号的话,两个符号之间不能有空格。>= 这是对的, > = 这是不对的。
1.3 逻辑运算符
- 逻辑运算符有:&、 | 、! 、&&、 ||
- 逻辑运算符两边要求都是布尔类型,并且最终的运算结果也是布尔类型。
- 关于短路与 &&,短路或 ||,其中重点学习短路与,短路或照葫芦画瓢。首先这两个运算符的运算结果没有任何区别,完全相同;只不过“短路与&&”会发生短路现象。
public class OperatorTest03{
public static void main(String[] args){
// 接下来需要理解一下什么是短路现象,什么时候会发生“短路”。
int x = 10;
int y = 11;
// 逻辑与&什么时候结果为true(两边都是true,结果才是true)
// 左边的 x>y 表达式结果已经是false了,其实整个表达式的结
// 果已经确定是false了,按道理来说右边的表达式不应该执行。
System.out.println(x > y & x > y++);
// 通过这个测试得出:x > y++ 这个表达式执行了。
System.out.println(y); // 12
//测试短路与&&
int m = 10;
int n = 11;
// 使用短路与&&的时候,当左边的表达式为false的时候,右边的表达式不执行
// 这种现象被称为短路。
System.out.println(m > n && m > n++);
System.out.println(n); // 11
}
}
- 什么时候使用&&,什么时候使用& ?从效率方面来说,&&比&的效率高一些。大部分情况下都建议使用短路与&&,只有当既需要左边表达式执行,又需要右边表达式执行的时候,才会选择逻辑与&。
1.4 赋值运算符
- 赋值运算符包括“基本赋值运算符”和“扩展赋值运算符”:基本的 =;扩展的:+=、 -= 、*=、 /= 、%=
- 注意:扩展赋值运算符在编写的时候,两个符号之间不能有空格。
- 使用扩展赋值运算符的时候,永远都不会改变运算结果类型。
public class OperatorTest04{
public static void main(String[] args){
/*
以 += 运算符作为代表,学习扩展赋值运算符。
其它的运算符,例如:-= *= /= %= 和 += 原理相似。
*/
int m = 10;
// += 运算符类似于下面的表达式
m = m + 20;
System.out.println(m); // 30
// 研究:
// i += 10 和 i = i + 10 真的是完全一样吗?
// 答案:不一样,只能说相似,其实本质上并不是完全相同。
byte x = 100; // 100没有超出byte类型取值范围,可以直接赋值
System.out.println(x); // 100
// 分析:这个代码是否能够编译通过?
// 错误: 不兼容的类型: 从int转换到byte可能会有损失
//x = x + 1; // 编译器检测到x + 1是int类型,int类型可以直接赋值给byte类型的变量x吗?
// 使用扩展赋值运算符可以吗?
// 可以的,所以得出结论:x += 1 和 x = x + 1不一样。
// 其实 x += 1 等同于:x = (byte)(x + 1);
x += 1;
System.out.println(x); // 101
// 早就超出byte的取值范围了。
x += 199; // x = (byte)(x + 199);
System.out.println(x); // 44 (当然会自动损失精度了。)
int y = 100;
y += 100;
System.out.println(y); // 200
y -= 100; // x = x - 100;
System.out.println(y); // 100
y *= 10; // x = x * 10;
System.out.println(y); // 1000
y /= 30; // x = x / 30;
System.out.println(y); // 33
y %= 10; // x = x % 10;
System.out.println(y); // 3
}
}
1.5 三目运算符
- 布尔表达式 ? 表达式1 : 表达式2
public class Test{
public static void main(String[] args){
// 这里会编译出错吗?
// 错误: 不是语句
// 100;
// 错误: 不是语句
//'男';
boolean sex = true;
// 分析以下代码是否存在语法错误?
// 错误: 不是语句
//sex ? '男' : '女';
// 前面的变量的c的类型不能随意编写。
// 最终的计算结果是字符型,所以变量也需要使用char类型。
char c = sex ? '男' : '女';
System.out.println(c);
}
}
1.6 字符串连接运算符
- + 运算符在java语言中有两个作用:求和、字符串拼接
- 当 + 运算符两边都是数字类型的时候,求和。
- 当 + 运算符两边的“任意一边”是字符串类型,那么这个+会进行字符串拼接操作,字符串拼接完之后的结果还是一个字符串。
测验:
关于 i = i++
public class Homework01{
public static void main(String[] args){
int i = 10;
i = i++;
// 大部分同学都会认为这个i一定是11
// 这个i变量最终的结果是10(惊讶)
// 在C++中运行结果确实是11.
// java中运行结果是10
// c++中运行结果是11
// 为什么?因为java和c++的编译器是不同的人开发的。原理不同。
System.out.println(i);
// 在java语言中i++,这种表达式在执行的时候,会提前先将i变量找一个临时
// 变量存储一下。(C++中并没有这样做。)
/*
int k = 10;
k = k++;
*/
int k = 10;
// k = k++;对应的是下面三行代码
int temp = k;
k++;
k = temp;
System.out.println(k);
}
}
接收键盘输入
public class KeyInput{
public static void main(String[] args){
// 创建一个键盘扫描器对象
// s 变量名,可以修改。其它不能改。
java.util.Scanner s = new java.util.Scanner(System.in); //还可以通过import方式,这里暂不介绍
// 接收用户的输入,从键盘上接收一个int类型的数据
// 解释这行代码,尽量让大家明白:代码执行到这里的时候,会暂停下来
// 等待用户的输入,用户可以从键盘上输入一个整数,然后回车,回车之后
// i变量就有值了。并且i变量中保存的这个值是用户输入的数字。
// i变量就是接收键盘数据的。
int i = s.nextInt(); // i是变量名,s是上面的变量名
System.out.println("您输入的数字是:" + i);
// 代码执行到此处又会停下来,等待用户的输入。
// 敲完回车,s.nextInt();代码执行结束。
int j = s.nextInt();
System.out.println("您输入的数字是:" + j);
// 如果输入的不是数字,那么会出异常:InputMismatchException
int m = s.nextInt();
System.out.println("您输入的数字是:" + m);
// 我怎么从键盘上接收一个字符串呢?
// 程序执行到此处会停下来,等待用户的输入,用户可以输入字符串。
String str = s.next();
System.out.println("您输入了:" + str);
}
}