Think in java 读书笔记
pikzas
2019.03.03
第3章-操作符
知识点
算数运算符
"+" 在处理字符串时候的特殊处理
常规的算数运算符有加减乘除取余赋值等(+-*/%=),这些操作符对于所有的基本数据类型都是可以直接使用的,但是对于对象还能有判定内存地址是否相等,是否不等,赋值(==,!=,=)操作符可以用。对于String这个特殊的引用对象类型,还可以使用拼接符(+),这是Java提供的一个语法糖,反编译字节码后,会发现”+“号会被StringBuffer的append方法代替。
"=" 在对象赋值过程中的特殊处理(别名现象)
发生这种现象是因为Java是值传递的,
对于基本数据类型,一个变量其实是指向堆栈中特定的值,在进行a=b这种赋值操作的时候,实际上是将b的值拷贝给了a变量。
对于引用数据类型,m=n这个操作,是将变量n所指向的对象的地址赋值给了m,这时候如果对m,n所指向的是同一个内存地址的同一个对象,无论是通过m还是n对对象有任何改变,所有指向该对象的引用(即变量)都会将这次的改变体现出来。
class Tank{ int level; } public class Demo{ Tank t1 = new Tank(); Tank t2 = new Tank(); t1.level = 12; t2.level = 34; print("--1--"+t1.level+"---"+t2.level); t1 = t2; // t1 变量的指针指向了t2 的所指向的那个对象 t1.level = 56; // 通过t1 对对象作出改变 print("--2--"+t1.level+"---"+t2.level); } // 打印结果 // --1--12---34 // --2--56---56
别名现象也会出现在方法调用上
public class Test { public static void f(int x) { x = 12; } public static void f2(String args) { args = "1234"; } public static void f3(Bean bean) { bean.x = 123; } public static void main(String[] args) { int y = 44; f(y); System.out.println(y); String str = "xxx"; f2(str); System.out.println(str); Bean bean = new Bean(); bean.x = 111; f3(bean); System.out.println(bean.x); } } class Bean{ public int x; } // 输出结果为 44 xxx 123 //为什么这个值发生了变化,而上面两个没有呢
除运算(/)在java中返回的值只有整数部分,不会四舍五入。
自动递增和递减
- 对于前缀递增和递减(++a或--a)会先执行运算,在生成值
- 对于后缀递增和递减(a++或a—-)会先生成值,在执行运算
class Demo{ public static void main(String[] args){ int i = 1; System.out.println("i: " + i); //1 System.out.println("++i:" + ++i); //2 System.out.println("i++:" + i++); //2 System.out.println("i: " + i); //3 System.out.println("--i:" + --i); //2 System.out.println("i--:" + i--); //1 } }
关系操作符
关系操作符返回的结果是布尔值 true 或者 false
所有的运算符包含 大于(>)、小于(<)、大于或等于(>=)、小于或等于(<=)、等于(==)、不等于(!=)。以上运算符可以作用在除布尔值以外的所有对象上。
- 布尔值只有true 或者 false 不存在谁比谁大。
- 以上运算符如果作用在引用数据类型的时候,比较的是其地址,如果需要比较对象的"值",则需要对该对象重载equals方法。默认的基础数据类型的包装类,都有做重写equals处理。
public class TestOne{ public static void main(String[] args) { Integer i1 = new Integer(1); Integer i2 = new Integer(1); System.out.println(i1 != i2); //true System.out.println(i1 == i2); //false System.out.println(i1 > i2); //false System.out.println(i1 < i2); //false System.out.println(i1.equals(i2)); //true } }
逻辑运算符
由于java是强类型语言,所以在进行逻辑运算的时候,参与运算的参数必须都是布尔类型,不能像js那样运行(123 && 123) = true。注意逻辑运算过程中的短路,一旦能确定运算结果,表达式就会停止运算再往后的表达式。
直接常量
一般我们在程序里都是用的数字都是十进制的,在指定情况下,也可以用二进制,八进制或者十六进制。
class Demo{ int i = 0x2f; // 0x或者0X 开头表示该数字为十六进制 int j = 0177; // 0 开头表示该数字为八进制 int m = 0b101; // 0b 开头表示该数字为二进制 int n = 100; // 默认情况下表示为十进制 long l = 123123123; long l1 = 234234234L; long l2 = 345345345L; float f = 123.234; float f1 = 12.333f; float f2 = 23.555F; double d1 = 1.234d; double d2 = 2.345D; }
16进制在表示一些特殊数字的时候比较方便,如char类型的占有2byte=16bits位,取值范围为 0 - 216-1,2的8次方✖️2的8次方-1=256×256-1=65535-1=0xffff-1
不同进制转换方法,假设数字是mab这样的格式 如果m=0x 代表这是16进制数字 那么将16进制的ab转换为10进制为: a×16(2-1) + b×16(1-1)
位操作符
位操作符号有 与(&)、或(|)、异或(^)、非(~)
先将数字转换为二进制,然后从右向左逐位取一位运算,将1看为true,0看为false。则位运算符与逻辑运算符类似,^可以看成如果两位相同,则取0,否则取1.
class Demo{ public static void main(String[] args){ System.out.println(1&1); // 1 System.out.println(1&0); // 0 System.out.println(0&1); // 0 System.out.println(0&0); // 0 System.out.println(1|1); // 1 System.out.println(1|0); // 1 System.out.println(0|1); // 1 System.out.println(0|0); // 0 System.out.println((0b11)^(0b11)); // 0 System.out.println((0b10)^(0b10)); // 0 System.out.println((0b11)^(0b10)); // 1 System.out.println((0b11)^(0b00)); // 3 // ~按位去反 输入0得1 输入1得0 } }
位移运算符
有符号的左移、右移(<<,>>)和无符号的右移(>>>)
类型转换
再将变量做类型转换的时候,若从较小的类型转换成较大的类型的时候,可以自动实现。反之则需要显式的申明,表明你已经知道可能存在的信息丢失的风险。
在将double 或者float 数据转换为int的时候,总是取数轴上离零点最近的那个值 (int)(29.5) = 29 、(int)(-29.5) = -29
如果想要实现四舍五入操作,需要使用Math.round(); 总是往大了转。
class Demo{ public static void main(String[] args){ System.out.println(Math.round(-29.3)); //-29 System.out.println(Math.round(-29.5)); //-29 System.out.println(Math.round(-29.7)); //-29 System.out.println(Math.round(29.3)); //29 System.out.println(Math.round(29.5)); //30 System.out.println(Math.round(29.7)); //30 } }
来源:https://www.cnblogs.com/Pikzas/p/12154360.html