java笔记
以下笔记皆为抄录,来源于《疯狂java讲义》
1.1 位运算符
- & 按位与。当两位同时为1时才返回1
- | 按位或。只要有一位为1即可返回1
- ~ 按位非。单目运算符,将操作数的每个位(包括符号位) 全部取反
- ^ 按位异或。当两位相同时返回0,不同时返回1。
- << 左移运算符。
- >> 右移运算符。
- >>> 无符号右移运算符
一般来说,位运算符只能操作整数类型的变量或值。按位非只需要一个操作数,这个运算符将把操作数在计算机底层的二进制码按位(包括符号位)取反。
<<:左移运算符是将操作数的二进制码位整体左移指定位数,左移后右边空出来的位以0填充。
例如 -5<<2
1111 1111 1111 1111 1111 1111 1111 1011 -5的原始二进制码位
1111 1111 1111 1111 1111 1111 1111 101100 -5的左移两位之后的二进制码位,因为最高位是1,所以进行转换之后的值为-20
>>:右移运算符,以0填充移出的位数,所以经过无符号右移的运算总会得到一个正数
例如5的二进制 为 0000 0000 0000 0000 0000 0000 0000 0101右移两位,二级制码位
000000 0000 0000 0000 0000 0000 0000 0101
规则
- 对于低于int类型(如byte,short和char)的操作数总是先自动类型转换为int类型后在位移。
- 对于int类型的整数移位a>>b,当b>32时,系统先用b对32求余(因为Int类型只有32位),得到的结果才是真正移位的位数。例如a>>33和a>>1的结果完全一样。long类型也是如此。
注意
- 当进行移位运算时,只要被移位的二进制码没有发生有效位的数字丢失(对于正数而言,通常指被移出的位全部都是0),不难发现左移n位就相当于乘以2的n次方,右移n位则是除以2的n次方。不仅如此,进行移位预算不会改变操作数本身,只是得到了一个新的运算结果,而原来的操作数本身是不会改变。
1.2 foreach循环
foreach循环迭代数组或者集合的时候不能改变原来数组的值。从下面的代码可以看出integer只是临时开创的一个变量,并没有真实的引用list里面的地址,进行改变值,只作为了一个临时接受list数据的变量。
public void test() {
List<Integer> l = new ArrayList<Integer>();
l.add(1);
l.add(2);
l.add(3);
l.add(4);
for (Integer integer : l) {
integer = 2;
System.out.println(integer);//输出2
}
System.out.println(l.get(0));//输出1
}
1.3 java的代码块
java中的代码块是一个假象,使用javac命令编译该类之后,该java类中的初始化代码块会消失,初始化的代码块会被"还原"到每个构造器中,且位于构造器所有代码的前面。如果是静态代码块呢?
1.4自动拆箱和自动封箱
java中会把一个 -128~127之间的整数自动装箱成Integer实例,并放入了一个名为cache的数组中缓存起来。所以把一个-18~127之间的整数自动装箱成一个Integer实例时,实际上是直接指向对应数组元素,所以他们全部相等。但如果不在这个范围内,系统会新创建一个Integer实例,这个时候进行比较的就是对象的比较,他们指向的并不是一个地址,所以不相等。
public class TestForeach {
public static void main(String[] args) {
//此时并不是从cache中取,而是通过创建一个integer的对象,
//因为Integer本身是引用类型,这时他们指向的又不是同一个地址
System.out.println(new Integer(2)==new Integer(2));//false
Integer a = 2;
Integer b = 2 ;
System.out.println(a==b);//true
a=150;
b=150;
System.out.println(a==b);//false
}
}