目录
1、类型转换
在Java程序中,不同基本类型的值经常需要进行相互转换
类型转换分为自动类型转换和强制类型转换
类型转换和布尔型没关系 , 类型转换是数值型数据进行的转换
自动类型转换
当把一个表数范围小的数值或变量直接赋值给另一个表数范围大的变量时,系统可以进行自动类型转换,当进行不同类型混合计算时,自动转成最大范围类型进行计算
强制类型转换
如同大瓶水倒入小瓶,两种结果:
1.大瓶水 ≤ 小瓶水,小瓶子能装下(强转没问题)
2.大瓶水 > 小瓶水,小瓶水溢出(强转会发生截断(按模取余)或可能溢出)
数据值没有丢失的前提:类型大的数值小于类型小的数值的最大取值范围
特别注意:在编程中要尽量避免由于强转导致的非预期结果
例如
byte b = (byte)200; b = -56;
200转成2进制 : 0 23个0 11001000
转成byte byte只有8位存储空间 , 那么就要从低位(后面)截取八位 截取之后的数据如下 :
11001000 源码
10110111 反码
10111000 补码
-(2^3+2^4+2^5) = -56
byte b = (byte)300 ; b = 44;
300二进制表示 : 0 22个0 100101100
截取八位是 00101100
类型强制转换语法格式 :
变量 = (type)变量
小类型变量 = (小类型)大类型数据;
2、运算符
2.1、算术运算符
运算符 | 运算 | 范例 | 结果 |
+ | 正号 | +3 | 3 |
- | 负号 | b = 4; -b; | -4 |
+ | 加 | 5 + 5 | 10 |
- | 减 | 6 - 1 | 5 |
* | 乘 | 3 * 5 | 15 |
/ | 除 | 10 / 2 | 5 |
% | 取模 | 5 % 5 | 0 |
++ | 自增(前) | a = 2; b = ++a; | a = 3; b = 3; |
++ | 自增(后) | a = 2; b = a++; | a = 3; b = 2; |
-- | 自减(前) | a = 2; b = --a; | a = 1; b = 1; |
-- | 自减(后) | a = 2; b = a--; | a = 1; b = 2; |
++ -- 说明:
++,自加,单目运算符
把++放左边,先把操作数+1,然后把操作数放入表达式中;(先加1,后取值)
把++放右边,先把操作数放入表达式中,然后把操作数+1;(先取值,后加1)
--,自减,单目运算符
把--放左边,先把操作数-1,然后把操作数放入表达式中;(先减1,后取值)
把--放右边,先把操作数放入表达式中,然后把操作数-1;(先取值,后减1)
思考题 :
public static void main(String[] args) {
int i = 5;
int y = i++ + i++ + ++i + i++ + i-- ;
System.out.println(i); // 8
System.out.println(y); // 36
}
2.2、位运算符
位运算符只能操作整型数据,byte char short 进行位运算时先升级类型为int;
位运算符只针对二进制来进行操作,在计算机中,正数用原码表示,负数用补码表示;
运算符 | 说明 | 示例 |
~ | 按位非运算(NOT)(一元运算符) | 0000 0101 => 1111 1010 |
& | 按位与运算(AND) | 0000 0101 & 0101 1011 = 0000 0001 |
| | 按位或运算(OR) | 0000 0101 & 0101 1011 = 0101 1111 |
^ | 按位异或(XOR) | 0000 0101 & 0101 1011 = 0101 1110 |
>> | 右移,左边空出位用符号位填补 | 8 >> 2 = 2 -8 >> 2 = -2 |
>>> | 右移,左边空出位用0位填补(无符号右移) | 8 >>> 2 = 2 -8 >>> 2 = 1073741822 |
<< | 左移,右边空出位用0位填补 | 2 << 2 = 8 -2 << 2 = -8 |
A | B | A | B | A & B | A ^ B | ~A |
0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
位非(~):一元操作符,操作数的第n位为1,那么结果的第n位为0,反之;
例: ~5 结果是 -6
5转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0101 |
1111 1111 1111 1111 1111 1111 1111 1010 |
位与(&):第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0;
例:5 & 3 结果是1;
5转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0101 |
3转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0011 |
0000 0000 0000 0000 0000 0000 0000 0001 |
位或(|):第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0;
例:5 | 3 结果是7;
5转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0101 |
3转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0011 |
0000 0000 0000 0000 0000 0000 0000 0111 |
位异或(^): 第一个操作数的的第n位于第二个操作数的第n位 相反,那么结果的第n为也为1,否则为0;
例:5 ^ 3 结果是6;
5转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0101 |
3转换为2进制 | 0000 0000 0000 0000 0000 0000 0000 0011 |
0000 0000 0000 0000 0000 0000 0000 0110 |
左移(<<) :右边空出位用0填补;
例:5 << 2 结果是20;
0000 0000 0000 0000 0000 0000 0000 0101 | 左移2位后,低位补0 |
0000 0000 0000 0000 0000 0000 0001 0100 | 换算成10进制为20 |
右移(>>):左边空出位用符号位填补;正数在前面补0 负数在前面补1
例:5 >> 2 结果是1;
0000 0000 0000 0000 0000 0000 0000 0101 | 右移2位,高位补0 |
0000 0000 0000 0000 0000 0000 0000 0001 |
无符号右移(>>>):左边空出位用0填补;不管正数负数都补0
例:-5 >> 3 结果是536870911;
-5换算成2进制 | 1111 1111 1111 1111 1111 1111 1111 1011 | |
-5右移3位后结果为-1,-1的二进制为 | 1111 1111 1111 1111 1111 1111 1111 1111 | 用1进行补位 |
-5无符号右移3位后的结果536870911换算成2进制 | 0001 1111 1111 1111 1111 1111 1111 1111 | 用0进行补位 |
2.3、赋值运算符 =
运算符 | 说明 | 示例 |
+= | 加赋值 | i = 4; i += 2; => i = i + 2; |
-= | 减赋值 | i = 4; i -= 2; => i = i - 2; |
*= | 乘赋值 | i = 4; i *= 2; => i = i * 2; |
/= | 除赋值 | i = 4; i /= 2; => i = i / 2; |
%= | 取余赋值 | i = 4; i %= 2; => i = i % 2; |
&= | 按位与赋值 | i = 4; i &= 2; => i = i & 2; |
|= | 按位或赋值 | i = 4; i |= 2; => i = i | 2; |
^= | 按位异或赋值 | i = 4; i ^= 2; => i = i ^ 2; |
>>= | 右移赋值 | i = 4; i >> 2; => i = i >> 2; |
>>>= | 右移赋值,左边空出位用0填补 | i = 4; i >>>= 2; => i = i >>> 2; |
<<= | 左移赋值 | i = 4; i <<= 2; => i = i << 2; |
扩展的赋值运算符 自带了一个隐藏起来的类型强制转换 ;
public class HelloWord {
public static void main(String[] args) {
int i = 5;
byte y = 3;
y += i; // 多了一个隐藏的类型转换
System.out.println(i);
System.out.println(y);
}
}
2.4、关系运算符
使用关系运算符进行运算 , 就是一个关系表达式 , 关系表达式都会返回一个 布尔结果 ; 该结果必须接收 ;
关系运算符决定值和值之间的关系,返回布尔型变量,结果不为真,必为假。
运算符 | 说明 | 示例 |
== | 等于 | 1 == 2 结果: false |
!= | 不等于 | 1 != 2 结果: true |
> | 大于 | 1 > 2 结果: false |
< | 小于 | 1 < 2 结果: true |
>= | 大于等于 | 1 >= 2 结果: false |
<= | 小于等于 | 1 <= 2 结果: true |
2.5、逻辑运算符
逻辑运算符的运算数只能是布尔类型,且逻辑运算的结果也是布尔类型
& | ^ 操作整型时是做位运算 , 操作布尔值时是做逻辑运算
运算符 | 说明 | 示例 boolean A = true, B = false; |
& | 逻辑与 | A & B 结果: false |
| | 逻辑或 | A | B 结果 : true |
^ | 异或 | A ^ B 结果: true |
|| | 短路径版 或运算 | A || B 结果: true |
&& | 短路经版 与运算 | A && B 结果: false |
! | 逻辑反 | !B 结果: true |
- ! 操作一个布尔值 , 真变假 , 假变真 ;
- ^ 亦或 操作两个布尔值 , 当且仅当一个为true 一个为false 时 , 表达式结果为 true , 反之false
- & 与 操作两个布尔值 , 当且仅当两个值都为true时 , 表达式结果为true 反之false
- | 或 操作两个布尔值 , 当两个中至少有一个值为true , 表达式结果为true ; 两个都为false时 表达式结果为 false;
- && 短路与 基本等价于 &
- || 短路或 基本等价于 |
布尔运算符的运算
A | B | A | B | A & B | A ^ B | !A |
False | False | False | False | False | True |
True | False | True | False | True | False |
False | True | True | False | True | True |
True | True | True | True | False | False |
短路与 短路或的验证代码如下 :
public class Test{
public static void main(String[] args){
int i = 5;
byte y = 3;
boolean b = 3 < 5 || i > y++;
System.out.println(b);
System.out.println(y);
}
}
2.6、三目(元)运算符
语法格式:
布尔值 ? 值1: 值2;
运算规则:先确定布尔值是真还是假 , 是真整个表达式结束返回值1作为表达式的结果 , 反之结束表达式 以值2作为表达式的结果
使用三元运算符可以代替简单的 if 语句
三元表达式的返回值结果:
值1 值2 可以是任意类型 , 两个值可以是不同类型 ;但是接收的时候会有问题
练习 :
对于两个整数 , 比较其大小 , 然后输出小的那个值
public class HelloWord {
public static void main(String[] args) {
int i = 5;
int y = 4;
int min = i > y ? y : i;
System.out.println("i = " + i + ", y = " + y + ", min = " + min);
}
}
2.7、运算符优先级
3、练习
对键盘录入的字节型数据 进行10进制到二进制表示形式的转换 (后期使用循环进行优化)
package com.hainiu;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请录入数据");
byte next = sc.nextByte();
System.out.println("录入的数据是 : "+next);
System.out.println("二进制标识 从右至左为 : ");
// 0 0000001 0 0000111
System.out.print(next>>7 & 1);
System.out.print(next>>6 & 1);
System.out.print(next>>5 & 1);
System.out.print(next>>4 & 1);
System.out.print(next>>3 & 1);
System.out.print(next>>2 & 1);
System.out.print(next>>1 & 1);
System.out.print(next & 1);
}
}