java基础学习笔记2
一、笔记内容概述:
关键字、标识符、注释、注释的应用、常量、进制的由来、进制转换、负数的进制、变量的介绍、变量的基本演示、类型提升&强制转换、字符类型运算过程、类型运算细节、算术运算符、赋值运算符。
二、常用内容介绍:
1.注释内容不占用内存,即使添加再多的注释,编译后生成的class文件占用硬盘的字节多少不变。
2.慎用强制转换,容易丢失精度,并且编译时也会报错,注意只要涉及到精度丢失时,编译器都不能
通过。
3.java内置的码表是Unicode码表,可以识别中文和英文。
三、经典示例及讲解:
1.分析下面代码强制转换后,输出结果的原因:
</pre><pre name="code" class="java">package com.demo;
/**
*分析下面强制转换后,输出结果的原因
*/
public class Demo1 {
public static void main(String[] args){
byte b = 3;
b = (byte) (b+200);
byte c = -3;
c = (byte)(c-127);
System.out.println(b);
System.out.println(c);
}
}
/**
*现象:为什么int型的203强制转换成byte型时,输出:-53
* 为什么int型的-130强制转换成byte型时,输出:126
*
*原理:当int型转换成byte型数据时,系统将会截取int数值的后8位(最右边8位),
* 同时以补码形式存储下来,并且最高位为符号位,根据符号位不同进行不同运算,因为正数补码就是其本身。
* 如果补码最高位是以0开头,说明截取下的是正数的byte型数值,直接按照二进制正常计算byte值;
* 如果补码最高位是以1开头,说明截取下的是负数的byte型数值。
* 除符号位外,其余部分先取反再加1,然后算出二进制所对应的byte数值,最后将负号加上。
*
*一、为什么int型的203强制转换成byte型时,输出:-53
* 因为:int型203对应的二进制为(省略了高位的无效0) 11001011,刚好8位。
* 强制转换时,系统自动截取最后8位,即11001011,因为最高位为1,所以按照最高位为1的方式进行计算。
* 符号位为:-
* 数值为:
* 1001011取反:0110100
* 0110100加1:0110101 -----对应数值为53,再加上符号位即,结果为-53。
*
*二、为什么int型的-130强制转换成byte型时,输出126
* 因为:int型-130对应的二进制为11111111 11111111 11111111 01111110
* 强制转换时,系统自动截取最后8位,即01111110,因为最高位为0,所以按照最高位为0的方式进行计算。
* 符号位:+(可以省略不写)
* 数值为:1111110 转换成十进制对应的数值为126。
*/
2.分析下面代码报错和不报错的原因:
package com.demo;
public class Demo2 {
public static void main(String[] args){
//1.
byte b = 3 + 7;
byte b1 = 3;
byte b2 = 7;
//b = b1 + b2;
System.out.println(b);
}
}
/**
*现象:为什么 byte b = 3+7;不报错?
* 为什么b = b1 + b2;时编译不能通过?
*错误原因:
* 涉及到编译器编译程序时候的细节,之所以byte b 3 +7;没有报错,是因为
* 3和7都是常量,编译器知道结果是10,并且在byte范围之内,因此就自动进行
* 了强转,所以不会报错。
* 而b = b1 + b2;中b1和b2都是变量,编译器编译程序
* 是一行一行编译的,它根本不知道b1和b2到底是多少,两个byte类型的数据相加
* 时,首先都会被提升为int类型,他们的和也是int类型,其值可能会超过byte的范围
* ,因为就会报错。
*/
3.分析下面输出结果:
package com.demo;
public class Demo3 {
public static void main(String[] args){
int x;
int x1 = Integer.MAX_VALUE;//整型的最大值
int x2 = 3;
x = x1 + x2;
System.out.println(x);
}
}
/**
*现象:为什么输出结果为:-2147483647,明显溢出了,编译器也不报错。
*说明:因为int类型的两个变量相加,最后还是int类型,虽然结果溢出,但是不会报错。
* java对于int型(其它类型也是一样的)数据溢出,并没有做编译时和运行时报错处理。
* 所以当数据溢出时,它自动截取二进制结果的最后32位,并留下来作为有效数据。
*/
4.思考下面的输出结果:
package com.demo;
public class Demo4 {
public static void main(String[] args){
System.out.println(5%5);
System.out.println(-5%2);
System.out.println(5%-2);
}
}
/**
*输出结果为:
* 0
-1
1
说明:
负数对正数取模结果为负数。
正数对负数取模结果为正数。
*/
5.分析下面两种方式的不同:
package com.demo;
public class Demo5 {
public static void main(String[] args){
short s = 3;
s += 4; //方式一
//s = s + 4; //方式二
System.out.println("s="+s);
}
}
/**
*为什么第一种方式不报错,而第二种方式报错?
*比较s += 4;和s = s +4;的不同。
*
*方式一:
* 在执行s += 4;语句时,编译器在编译的时候,默认进行了强制类型转换,也就是将
* int类型的数值自动转换成了short类型的数据。
*
*方式二:
* 说明执行s = s + 4;语句时,编译器在编译的时候,默认并没有强制转换。所以,s是short
* 类型,4是int类型,执行s + 4加操作时,首先s会自动转型为int类型,然后再执行加操作,最后的
* 结果也是int类型,赋值给short类型的s变量,肯定会损失精度,这时候就需要进行强制类型转换,
* s = (short)(s+4);
*/
6.思考下面运算的特点
package com.demo;
public class Demo6 {
public static void main(String[] args){
int x = 10;
//float y = 1.2;
float y = 1.2f;
y = y + 10;
System.out.println(y);
}
}
/**
*错误原因:
* 由于小数默认是double(8位)类型,赋值给float(4位)类型的变量,当然可能会
* 损失精度,必然通不过编译器的审核。
*解决方法:在数值的后面加上一个"f",让编译器知道后面的常量是float类型的。
*
*现象:y = y+ 10;为什么编译和运行时都不报错?
* int类型和float类型的数值进行相加时,int类型先会转换成float类型然后执行加操作,
* 最终结果还是float类型,所以不报错。
*/