最近在整理由于比较空余,花了点时间把之前的学习笔记搬一下
1、基础运算符 加(+)、减(-)、乘(*)、除(/)、等号(=)
优先级跟我们数学一样,乘除优先,加减次之,等号最后,加减乘除没什么好说的,主要注意的等号(赋值运算符)
上面一章(一切都是对象)的学习也知道,操作对象是通过对象的句柄来操作,句柄和对象位于不同的内存空间,句柄位于栈区,对象位于堆区,操作对象的句柄可以有多个,句柄消失了,对象依然存在,等待垃圾回收器处理,所以在 赋值运行里对 句柄的赋值,并不改变对象,例如句柄 A = B; 那么句柄A和句柄B都控制同一个对象,通过A或者B来改变对象,会同时作用到A句柄和B句柄。
class Number{
int i;
}
public class Assignment{
public static void main(String[] argv){
Number n1 = new Number(); //new一个对象并保存到n1句柄中
Number n2 = new Number(); //new一个对象并保存到n2句柄中
n1.i = 10; //通过n1句柄给对象设置i的值为10
n2.i = 20; //通过n2句柄给对象设置i的值为20
System.out.println("first: n1.i=" + n1.i + "; n2.i=" + n2.i); //通过n1和n2句柄打印相应对象中 i 的值
n1 = n2; //此时句柄n1 和 n2都控制着之前n2一直控制的对象,n1之前控制的对象依然在堆区中,有可能会被垃圾回收器销毁
System.out.println("second: n1.i=" + n1.i + "; n2.i=" + n2.i); //通过n1和n2句柄打印相应对象中 i 的值
n1.i = 15; //通过句柄n1修改对象中i的值,此时句柄n2控制的值也改变了,因为两者都是控制着同一个对象
System.out.println("third: n1.i=" + n1.i + "; n2.i=" + n2.i); //通过n1和n2句柄打印相应对象中 i 的值
}
}
输出结果:
另外加法运算符在java里有一个比较特殊而且时非常常见的用途就是连接字符串,像上面的例子里就可以看到
2、自动递增(++)和自动递减(--)
对于自动递增和自动递减,故名思议就是在原始基础上增加1或者减少1,需要注意的是,递增和递减后,数值什么时候保存到变量中
前--或者++,是在保存数据在变量之前进行运行
i = 10
--i // i 的值为9
++i // i 的值在9的基础上加1 为10
后--或者++,是在保存数据在变量之后进行运行
i = 10
i-- // i 依然是10
i++ //i 的值依然是10
3、关系运算符
关系运算符主要有 大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、等于(==)、不等于(!=),关系运算符的运算结果是真(true)或者假(false),另外需要注意的一点是等于和不等于除了可以比较基本数据类型,也可以比较句柄。再强调一次,句柄是用于控制对象的,对象和句柄不在同一个内存空间。
class Value{
int i;
}
public class EqualsMath{
public static void main(String[] argv){
Integer n1 = new Integer(20);
Integer n2 = new Integer(20);
System.out.println(n1 == n2); //fase n1 和n2通过创建对象的方式产生整型数据句柄,两个句柄是不一样的,虽然都是控制数值都是20
System.out.println(n1 != n2); // true n1 和n2通过创建对象的方式产生整型数据句柄,两个句柄是不一样的,虽然都是控制数值都是20
System.out.println(n1.equals(n2)); // true 通过Integer对象的equals方法可以比较Integer对象的值,因而这里是true
Integer n3 = new Integer(30);
Integer n4 = new Integer(40);
System.out.println(n3.equals(n4)); // false 通过Integer对象的equals方法可以比较Integer对象的值,句柄n3和句柄n4控制的对象数值不一样,因而这里是fase
Value v1 = new Value();
Value v2 = new Value();
v1.i = 10;
v2.i = 10;
System.out.println(v1 == v2); // v1 和 v2 句柄不一样,所以返回false
System.out.println(v1 != v2); // v1 和 v2 句柄不一样,所以返回true
System.out.println(v1.equals(v2)); // 这里返回false是因为我们自己创建的类默认equals方法是比较句柄的,而上面的Integer类equals方法已经修改过了,用于比较数值,一般java库里面类的equals方法都修改成了比较数值
}
}
4、逻辑运算符
逻辑运算符包括 与(&&)、或(||)、非(!),逻辑运算符跟我们的数学与或非是一样的,最终得到的结果是真(true)或者假(false),需要注意的是,用于逻辑表达式的值必须为布尔值(true或者false),例如:
int i = 10;
int j = 20;
i && j---------------------->这个表达式是错误的,因为 && 逻辑运算符左右两边的数据都不是布尔类型
(i >=10) && (j>=10) --->这个表达式是正确的,因为&&逻辑运算符左右两边的数据是布尔类型
另外逻辑运算也要注意短路现象,也就是如果前面的逻辑运算表达式成立了,就不再测试后面的逻辑运算,例如
int i = 10;
int j = 20;
int k = 30;
if((i>=10) && (j>=30) && (k>=30)) ---> 先测试 i>=10 是否成立,成立了再测试 j >= 30是否成立,此时不成立,那么 k>=30就不再测试了
if((i>=10) || (j>=30) || (k>=30)) ---->先测试 i>=10 是否成立,成立了,后面或运算的 j>=30 和 k>=30 就不再测试了
5、按位运算符
按位运算符主要使用在整型的主数据类型中,用于整数的每一位进行逻辑操作,然后生成最终数据,运算符包括 按位与(&)、按位或(|)、按位非(~)、按位异或(^)
按位与(&),两个整数按位与时,相应位都为1,则为1
按位或(|),两个整数按位或时,只有一位为1,则为1,相应位都为0,则为0
按位异或(^),两个整数按位异或时,只有一位为0,则为1,相应位都为1,则为0
按位非(~),一个整数按每一位取反,即0为1,1为0得到新的整数
6、移位运算符
移位运算符使用在整数的主数据中,主要有左移运算符(<<)、有符号右移运算符(>>)、无符号右移运算符(>>>)
左移运算符(<<),数据按位往左移动指定位数,低位补0
有符号右移运算符(>>),向右移动按位移动指定位数,如果原始数据为正,则最高为补0,其他空 位补0,如果原始数据为负,则最高位补1,其他空位补0
无符号右移运算符(>>>),向右移动按位移动指定位数,最高为补0,其他空 位补0