- 基本数据类型,自动转换
//细节 1: 有多种类型的数据混合运算时,
//系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
int n1 = 10; //ok
float d1 = n1 + 1.1;//错误 n1 + 1.1 => 结果类型是 double
double d1 = n1 + 1.1;//对 n1 + 1.1 => 结果类型是 double
float d1 = n1 + 1.1F;//对 n1 + 1.1 => 结果类型是 float
//细节 2: 当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时,
//就会报错,反之就会进行自动类型转换。
//
//int n2 = 1.1;//错误 double -> int
//细节 3: (byte, short) 和 char 之间不会相互自动转换
//当把具体数赋给 byte 时,(1)先判断该数是否在 byte 范围内,如果是就可以
byte b1 = 10; //对 , -128-127
// int n2 = 1; //n2 是 int
// byte b2 = n2; //错误,原因: 如果是变量赋值,判断类型
//
// char c1 = b1; //错误, 原因 byte 不能自动转成 char
//细节 4: byte,short,char 他们三者可以计算,在计算时首先转换为 int 类型,
byte b2 = 1;
byte b3 = 2;
short s1 = 1;
//short s2 = b2 + s1;//错, b2 + s1 => int
int s2 = b2 + s1;//对, b2 + s1 => int
//byte b4 = b2 + b3; //错误: b2 + b3 => int,同一种计算也自动转换为int
System.out.println('男'+'女');//输出52906,男女码值加的结果
//细节5:boolean 不参与转换
boolean pass = true;
//int num100 = pass;// boolean 不参与类型的自动转换:
2、强制类型转换
//细节一:强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
//int x = (int)10*3.5+6*1.5;//编译错误: double -> int
int x = (int)(10*3.5+6*1.5);// (int)44.0 -> 44
System.out.println(x);//44
//细节二,char可以保存int类型常量值,不能保存变量值,需要强转
char c1 = 100; //ok
int m = 100; //ok
//char c2 = m; //错误
char c3 = (char)m; //ok
System.out.println(c3);//100 对应的字符, d 字
3、基本数据类型和string转换
//基本数据类型->String,后边加上""
int n1 = 100;
float f1 = 1.1F;
double d1 = 4.5;
boolean b1 = true;
String s1 = n1 + "";
String s2 = f1 + "";
String s3 = d1 + "";
String s4 = b1 + "";
System.out.println(s1 + " " + s2 + " " + s3 + " " + s4);
//String->对应的基本数据类型
String s5 = "123";
//解读 使用 基本数据类型对应的包装类,的相应方法,得到基本数据类型
int num1 = Integer.parseInt(s5);
double num2 = Double.parseDouble(s5);
float num3 = Float.parseFloat(s5);
long num4 = Long.parseLong(s5);
byte num5 = Byte.parseByte(s5);
boolean b = Boolean.parseBoolean("true");
short num6 = Short.parseShort(s5);
System.out.println("===================");
System.out.println(num1);//123
System.out.println(num2);//123.0
System.out.println(num3);//123.0
System.out.println(num4);//123
System.out.println(num5);//123
System.out.println(num6);//123
System.out.println(b);//true
//怎么把字符串转成字符 char -> 含义是指 把字符串的第一个字符得到
//解读 s5.charAt(0) 得到 s5 字符串的第一个字符 '1'
System.out.println(s5.charAt(0))
//细节一:在将 String 类型转成 基本数据类型时,
//比如 我们可以把 "123" , 转成一个整数,但是不能把 "hello" 转成一个整数,
//如果格式不正确,就会抛出异常,程序就会终止这个问题在异常处理章节中,会处理
3、
System.out.println(11.11+11.12);//小数运算出一个近似值,输出22.229999999999999999997
System.out.println(11.11+11.11);//输出22.22,可能理解成了乘法,就没有运算出一个近似值??
System.out.println(11.11*2);//输出22.22
4、%的本质
TODO:下边小数取余运算为啥有的是近似值,有的不是????????
// % 取模 ,取余
// 在 % 的本质,a % b = a - a / b * b
// -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1
// 10 % -3 = 10 - 10 / (-3) * (-3) = 10 - 9 = 1
// -10 % -3 = (-10) - (-10) / (-3) * (-3) = -10 + 9 = -1
System.out.println(10 % 3); //1
System.out.println(-10 % 3); // -1
System.out.println(10 % -3); //1
System.out.println(-10 % -3);//-1
//当a是小数时,a % b = a-(int)a/b*b
System.out.println(-10.5%3); //-10.5-(-10)/3*3=-10.5-(-9)=-1.5,为啥不是近似值??
System.out.println(-10.4%3); //-1.400000000000000000004,是个近似值
5、i++和++i的本质
int i = 1;//i->1
i = i++; //规则使用临时变量: (1) temp=i=1;(2) i=i+1=2;(3)i=temp=1;
System.out.println(i); // 1
i=++i; //规则使用临时变量: (1) i=i+1=2;(2) temp=i=2;(3)i=temp=2;
System.out.println(i); //2
6、&&和&,||和|的区别
//&&短路与 和 & 案例演示
int age = 50;
if(age > 20 && age < 90) {
System.out.println("ok100");
}
//&逻辑与使用
if(age > 20 & age < 90) {
System.out.println("ok200");
}
//区别
对于&&短路与而言,如果第一个条件为 false ,后面的条件不再判断
//对于&逻辑与而言,如果第一个条件为 false ,后面的条件仍然会判断
//
//|| 和|同理
//||短路或:如果第一个条件为 true,
//则第二个条件不会判断,最终结果为 true,效率高
//| 逻辑或:不管第一个条件是否为 true,第二个条件都要判断,效率低
int a = 4;
int b = 9;
if(a < 1 & ++b < 50) {
System.out.println("ok300");
}
System.out.println("a=" + a + " b=" + b);// 4 10
7、逻辑运算符 异或^
ture ^flase=true
true^ture=true
不同为真,相同为假
8、+=,++类型转换
//复合赋值运算符会进行类型转换
byte b = 3;
b += 2; // 等价 b = (byte)(b + 2);
b++; // b = (byte)(b+1
9、三元表达式
条件表达式 ? 表达式 1:表达式2;
真就表达式一
//案例:实现三个数的最大值
int n1 = 553;
int n2 = 33;
int n3 = 123;
int max = (n1 > n2 ? n1 : n2) > n3 ?
(n1 > n2 ? n1 : n2) : n3;
System.out.println("最大数=" + max);
三元运算符看做一个整体,表达式1和表达式2也存在优先级关系
感觉“:”也是一个运算符,会实现自动类型转换(比如像double=int+double)
实践
public class ExerChapter12 {
public static void main(String[] args) {
Object o=true?new Integer(1):new Double(2.0);
System.out.println(o);//输出1.0
o=true?1:2.0;
System.out.println(o);//输出1.0
}
}
对第三行进入源码,发现其中部分执行顺序是
在Integer.intValue()时,value值还是1,然后下一步直接运行Double.valueOf,值变成了1.0
对第五行debug时,直接就认为o是double型1.0了,随后继续执行执行Double.valueOf
10、运算符优先级
11、标识符命名规范
- 包名:多单词组成时所有字母都小写:aaa.bbb.ccc
- 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
12、键盘输入语句
引入包import java.util.Scanner;
Scanner myScanner=new Scanner(System.in);
String name=myScanner.next();
int age=myScanner.nextInt();
System.out.println(name);
System.out.println(age);
//接受字符
char c=myScanner.next().charAt(0);
13进制转换
10->2,除2区域法,倒着看
//n1 二进制,0b开头
int n1 = 0b1010;
//n2 10 进制,无开头
int n2 = 1010;
//n3 8 进制,0开头
int n3 = 01010;
//n4 16 进制,0x开头
int n4 = 0X1010
14、位运算
java 中有 7 个位运算(&、|、 ^ 、~、>>、>>),以补码运算
- &,按位与,全为1,结果为1,否则为0
- |,按位或,至少一个1,结果为1,否则0
- ^,异或,不同为1,相同为0
- ~,按位取反,0->1,1->0
- >>:算术右移,低位溢出,符号位不变,并用符号位补溢出的高位
- >>:算术左移,符号位不变,低位补 0
- >>>:逻辑右移也叫无符号右移,运算规则是: 低位溢出,高位补 0
- 没有<<<
//&
//按位与过程
2的原码为 00000000 00000000 00000000 00000010
//2的补码为 00000000 00000000 00000000 00000010
//3的补码为 00000000 00000000 00000000 00000011
//按位与: 00000000 00000000 00000000 00000010
//补码转原码 00000000 00000000 00000000 00000010
//即结果为2
System.out.println(2&3);
//>>
//正数算数右移,高位补符号位(0)
byte b1=1;
System.out.println(b1>>2);//1 => 00000001 => 00000000 本质 1 / 2 / 2 =0
//>>
//负数算术右移,高位补符号位(1)
// -20 的二进制原码 :1001 0100
// -20 的二进制反码 :1110 1011
// -20 的二进制补码 :1110 1100
// 右移两位后的补码:1111 1011
// 反码:1111 1010
// 原码:1000 0101
// 结果:r = -5
byte b2=-20;
System.out.println(b2>>2);
//<<
//算术左移,低位补0
// -20 的二进制原码 :1001 0100
// -20 的二进制反码 :1110 1011
// -20 的二进制补码 :1110 1100
// 左移两位后的补码:1011 0000
// 反码:1010 1111
// 原码:1101 0000
// 结果:r = -80
byte b3=-20;
System.out.println(b3<<2);
//>>>
//逻辑右移,高位补0,无论正负
//正数: r = 20 >>> 2
// 的结果与 r = 20 >> 2 相同;
// 负数: r = -20 >>> 2
// -20:源码:10000000 00000000 00000000 00010100
// 反码:11111111 11111111 11111111 11101011
// 补码:11111111 11111111 11111111 11101100
// 右移:00111111 11111111 11111111 11111011
// 结果:r = 1073741819
System.out.println(-20>>>2);
15、理解if(a=flase){}
理解这段代码的关键是理解赋值运算符(=),赋值运算符和 +,- 一样是一个二元运算符,它进行的运算是:将右运算数的值赋给左运算数,表达式返回右运算数的值。
所以如果执行if(a=flase)
得到的是 if(false)。
这也是为什么赋值运算符可以连接使用