Java之操作符

Java操作符

赋值操作符

  • 操作符:赋值(=)
  • 作用:把右值赋给左值
    • 左值:必须是一个明确的、已命名的变量。
    • 右值:右值可以时任何常数、变量或表达式。
  • 对基本类型赋值:基本类型存储了实际的数值,而非引用,所以赋值时是将一个地方的内容复制到另一个地方
    • 如对基本数据使用a=b,那么b的内容直接复制给a,如果此时再修改a的值,它是不会影响b的值的。
      •  int a = 0;
         int b = a;
         b = 1;
         System.out.println("a = " + a + ", b = " + b);
         
         输出:
         a = 0, b = 1
        
    • 对向方法中传入基本类型的变量,会将变量的实参复制一份给形参,如果再在方法修改变量的值是不会影响实参的,因为此时是在修改形参的值。
      •  static void test(int a) {
         	a = 1;
         }
         
         int a = 0;
         System.out.println("before a = " + a);
         test(a);
         System.out.println("after a = " + a);
         
         输出:
         before a = 0
         after a = 0
        
  • 对对象赋值:我们在操作对象时其实操作的是对象的引用, 所以赋值时是将引用复制到了另一个地方,对象没有被复制
    • 如对对象使用c=d,那么c和d将指向同一个对象,如果此时修改c的某个属性,通过d打印该属性,你将发现d的属性的值和c的一样,因为它们本来引用的就是同一个对象而已。
      •  class Test {
         	public int a;
         }
         
         Test c = new Test();
         c.a = 0;
         System.out.println("before c.a = " + c.a + ", c = " + c);
         Test d = c;
         d.a = 1;
         System.out.println("after c.a = " + c.a + ", c = " + c);
         System.out.println("after d.a = " + d.a + ", d = " + d);
         
         输出:
         before c.a = 0, c = com.eos.javalearn.Test@2401f4c3
         after c.a = 1, c = com.eos.javalearn.Test@2401f4c3
         after d.a = 1, d = com.eos.javalearn.Test@2401f4c3
        
    • 同理,向方法中传入对象也只是传递了一个引用,如果在方法中修改的某个属性是可以修改的。
      •  class Test {
         	public int a;
         }
         
         static void test(Test test) {
         	test.a = 1;
         }
         
         Test test = new Test();
         test.a = 0;
         System.out.println("before a = " + test.a);
         test(test);
         System.out.println("after a = " + test.a);
         
         输出:
         before a = 0
         after a = 1
        
    • 如果将对象传入方法,同时让其引用一个新的对象,这是不会起作用的,因为只是将实参的引用复制给了形参,在引用新的对象时,是让形参去引用,而不是实参引用。
      •  class Test {
         	public int a;
         }
         
         static void test(Test test) {
         	System.out.println("before a = " + test.a + ", 形参test = " + test);
         	Test test1 = new Test();
         	test1.a = 1;
         	System.out.println("a = " + test1.a + ", 局部变量test1 = " + test1);
         	test = test1;
         	System.out.println("after a = " + test.a + ", 形参test = " + test);
         }
         
         Test test = new Test();
         test.a = 0;
         System.out.println("before a = " + test.a + ", 实参test = " + test);
         test(test);
         System.out.println("after a = " + test.a + ", 实参test = " + test);
         
         输出:
         before a = 0, 实参test = com.eos.javalearn.Test@2401f4c3
         before a = 0, 形参test = com.eos.javalearn.Test@2401f4c3
         a = 1, 局部变量test1 = com.eos.javalearn.Test@7637f22
         after a = 1, 形参test = com.eos.javalearn.Test@7637f22
         after a = 0, 实参test = com.eos.javalearn.Test@2401f4c3
        

算数操作符

  • 操作符:加(+)、减(-)、乘(*)、除(/)、取余(%)。
  • 取余运算:
    • 性质:对所有int数值a和所有非零int数值b满足:(a / b ) * b + (a % b) == a。
    • 因此,a%b = a-(a/b)*b
    • 比如:
      • 10%3 = 10 - (10/3)*3 = 10 - 3 * 3 = 10 - 9 = 1。
      • 3%10 = 3 - (3/10)*10 = 3 - 0 * 10 = 3 - 0 = 3。
  • 整数除法会直接去掉结果的小数位,而不是四舍五入
  • Java也使用一种来自c和c++的简化符号同时进行运算与赋值操作。
    • x += 1等同于x = x + 1
  • 一元加、减操作符:
    • 一元减号和一元加号和二元减号和加号使用的符号是相同的,分别是-和+。
    •   int a = 1;
        int b = -a;         //一元减号相当于负号
        int c = a + -b;     //可以这样写,编译器会自动判断,但是影响可读性
        int d = c / (-b);   //建议这样写
        System.out.println("a = " + a + ", b = " + b + ", c = " + c + ", d = " + d);
        
        输出:
        a = 1, b = -1, c = 2, d = 2
      
    • 一元减号就相当于负号,对应的一元加号却仅仅只有一元减号的另一个作用——将较小类型的操作数提升为int。
      • 这些较小类型包括char、short和byte。
      • 如果对int、long、float、long使用一元减号,就是将它们转换为对应的负数。
      • 一元减号和一元加号不作用于boolean类型。
      •  //前3个都有问题
         byte a = 0;
         byte b = +a;
         byte c = -a;
        
         short d = 0;
         short e = +d;
         short f = -d;
        
         char g = '0';
         char h = +g;
         char i = -g;
        
         //以下的都没问题
         float j = 0.1f;
         float k = +j;
         float l = -j;
        
         double m = 0.1d;
         double n = +m;
         double o = +m;
        
         long p = 10l;
         long q = +p;
         long r = -p;
        
         int s = 1;
         int t = +s;
         int u = -s;
        

自增、自减运算符

  • 操作符:自增(++)自减(--)
  • 作用:使变量的值加一或减一,同时以改变后的值作为变量的新值。
  • 这两个操作符各有两种使用方式:
    • 前缀式:先执行运算,再生成值。
    • 后缀式:先生成值,再执行运算。
    •  int i = 1;
       System.out.println("i = " + i);
       System.out.println("++i = " + ++i);
       System.out.println("i++ = " + i++);
       System.out.println("i = " + i);
       System.out.println("--i = " + --i);
       System.out.println("i-- = " + i--);
       System.out.println("i = " + i);
       
       输出:
       i = 1
       ++i = 2
       i++ = 2
       i = 3
       --i = 2
       i-- = 2
       i = 1
      

关系操作符

  • 操作符:小于(<)大于(>)小于或等于(<=)大于或等于(>=)等于(==)不等于(!=)
  • 作用:用于计算操作数的值之间的关系。如果是关系是真实的,关系表达式会生成true;否则生成false。
  • 等于和不等于适用于所有的基本数据类型,而其他比较符不适用于boolean类型。因为boolean值只能为true或false,大于或小于对它来说没有意义。
  • 等于和不等于:
    • 比较基本类型用==或!=。
    • 两个对象用==或!=是比较引用是否相同。
  • 一般来说,比较对象用equals()方法,同时,基本类型不能用该方法,因为只有对象才有这个方法。
  • equals()方法的默认行为是比较引用。大多数Java类库都实现了equals()方法,以便用来比较对象的内容,而非比较对象的引用。
    •  Integer a = new Integer(1);
       Integer b = new Integer(1);
       System.out.println("a==b = " + (a == b));
       System.out.println("a!=b = " + (a != b));
       System.out.println("a.equals(b) = " + a.equals(b));
       
       输出:
       a==b = false
       a!=b = true
       a.equals(b) = true
      

逻辑操作符

  • 操作符:与(&&)或(||)非(!)
  • 作用:可以根据参数的逻辑关系生成一个布尔值。
  • 与、或、非操作只可应用于布尔值。
  • 布尔值与String一起用时会自动转换成文本形式。
  • 当使用逻辑操作符时,会有一种短路现象。即一旦能够明确无误地确定整个表达式的值,就不会再计算表达式余下的部分了,这种现象将带来性能上的提升。
    • 如:1 < 2 && 2 >3 && 3 < 4
    • 第1个比较运算结果为true,接着比第2个,发现为false,由于与的关系,需要三个表达式都为true时最后的结果才为true,此时发现了一个false,因此就不会再计算第3个比较运算的结果了,它会直接返回false。
    •  int a = 1;
       int b = 2;
       int c = 3;
       System.out.println("a < b && b < c = " + (a < b && b < c));
       System.out.println("a > b || b > c = " + (a > b || b > c));
      
       boolean d = false;
       System.out.println("!d = " + !d);
       
       输出:
       a < b && b < c = true
       a > b && b > c = false
       !d = true
      

按位操作符

  • 操作符:按位与(&)按位或(|)按位非(~)按位异或(^)
  • 作用:用来对两个参数中对应的二进制位执行布尔代数运算,并生成一个结果。
    • 按位与:二元操作符,两个位都为1,结果才为1,否则为0。
      • 3&5=1:
      •          0000 0011
         &       0000 0101
         —————————————————
         		 0000 0001
        
    • 按位或:二元操作符,两个位中只要有一个位为1,结果就为1,否则为0。
      • 3|5=7:
      •          0000 0011
         |       0000 0101
         —————————————————
         		 0000 0111
        
    • 按位异或:二元操作符,两个位相同就为0,否则就为1。
      • 3^5=6:
      •          0000 0011
         ^       0000 0101
         —————————————————
         		 0000 0110
        
    • 按位非:一元操作符,对位进行取反,如果是1,结果就是0;如果是0,结果就是1。
      • ~5=-6:
      •  ~       0000 0101
         —————————————————
         		 1111 1010
        
    • ABA&BA|BA^B~A
      000001
      100110
      010111
      111100
  • 按位操作符可与等号联用,如&=、|=、^=。由于按位非是一元操作符,它不可以与等号联用。
  • 可以把布尔类型作为一种单比特值对待,它可以进行按位与、按位或、按位异或操作,但不能进行按位非操作,可能是为了避免与逻辑非混淆。
    • 布尔的按位运算符和逻辑操作符效果相同,但是它没有短路现象。
    • ABA&BA|BA^B
      truetruetruetruefalse
      truefalsefalsetruetrue
      falsetruefalsetruetrue
      falsefalsefalsefalsefalse
  • 按位与的应用:
    • ①归零:
      • 	 1101 1111
         &   0000 0000
          ————————————
         	 0000 0000
        
    • ②取指定位:
      •      1010 1110
         &   0000 1111
         —————————————
         	 0000 1110
        
    • ③判断奇偶
      •      0000 0101
         &   0000 0001
         —————————————
         	 0000 0001
        
  • 按位或的应用:
    • 将某些为设置为1
      •      1010 1110
         |   0000 1111
         —————————————
         	 1010 1111
        
  • 按位异或的应用:
    • 翻转指定位:
      •      1010 1110
         ^   0000 1111
         —————————————
         	 1010 0001
        

移位操作符

  • 操作符:左移位(<<)右移位(>>)逻辑右移位(>>>)
  • 移位操作符只能用来处理整数类型。
    • 左移位:按照右侧指定的位数将左边的操作数向左移动(在低位补0,高位丢弃)。
    • 右移位:按照右侧指定的位数将左边的操作数向右移动(低位丢弃,若符号为正,则在高位插入0;若为负,则插入1)。
    • 逻辑右移位:按照右侧指定的位数将左边的操作数向右移动(低位丢弃,无论正负,都在高位插入0)。
  • 对char、byte、short类型的数值进行移位处理时,会先将它们转换为int型再进行移位,并且得到的结果也是int类型。
  • 移位操作符可与等号联用,如<<=、>>=、>>>=。
  • 对short或byte的值进行逻辑右移位运算时,它会先转换成int型,在进行右移操作,然后被截断,赋值给原来的类型,这种情况下极有可能得到-1的结果。

三元操作符

  • 形式:boolean=exp ? value1 : value2
  • 三元操作符也叫条件操作符,布尔表达式boolean=exp的结果为true,则整个表达式的结果就为value1,否则为value2。
    •  int a = 10;
       int b = 20;
       int c = a > b ? a : b;
       System.out.println("c = " + c);
       
       输出:
       c = 20
      

类型转换操作符

  • 作用:允许我们显示地进行类型转换。
  • 既可以对数值进行类型转换,也可以对变量进行类型转换。
  • 例子:int a = (int) 0.1;
  • 转换分类:
    • 窄化转换:将能容纳更多信息的数据类型转化成无法容纳那么多信息的类型。这就意味着可能会丢失信息。需要显式地进行类型转换,编译器会前置进行类型转换。
      • 浮点数窄化为整型值时,总是对数字进行截尾。如果想得到四舍五入的结果,可以使用Math类的round()方法。
    • 扩展转换:不必显示地进行类型转换。因为新类型能容纳原来的信息,不会有任何丢失。
    •  int a = 200000;
       //窄化转换
       short b = (short) a;
       //扩展转换
       long c = a;
       System.out.println("a = " + a + ", b = " + b + ", c = " + c);
       
       输出:
       a = 200000, b = 3392, c = 200000
      
  • Java允许我们把任何基本数据类型转换成别的基本数据类型,但布尔型除外,后者根本不允许进行任何类型的转换处理。
  • 其他:
    • 在对基本数据类型执行算术或按位运算时,只要比int小 ,运算前都会先自动转换成int再进行运算,同时得到的结果也是int型,如果想要把结果赋值给较小的类型,就必须使用类型转换。
    • 对于上一条来说,通常默认的整数就是int,所以不用表明,但是如果两个int进行运算,可能出现结果超出int范围的值,这是编译器可能不会显示错误信息或发出警告,运行时也不会出现异常,但需注意。
    • 通常,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型。
      • 如果将一个float值与一个double值相乘,结果就是double型。
      • 如果将一个int值与一个long值相加,结果就是long型。

运算符优先级

  • 如果不使用括号将按照以下优先级次序进行计算。
    • a && b || c等同于(a && b) || c
  • 同一级别的运算符按照从左到右的次序进行计算,但右结合运算符除外。
    • a += b -= c等同于a += (b -= c)

优先级从高到低:

运算符结合性
[].()(方法调用)从左向右
!~++--+(一元运算)-(一元运算)()(强制类型转换)new从右向左
*/%从左向右
+-从左向右
<<>>>>>从左向右
<<=>>=instanceof从左向右
==!=从左向右
&从左向右
^从左向右
|从左向右
&&从左向右
||从左向右
?:从右向左
=+=-=*=/=%=&=|=^=<<=>>=>>>=从右向左

直接常量

如果使用了直接常量,编译器能辨认出它是什么类型,但有时候又不一定。
我们需要用一些字符来增加类型的具体信息。

  • 直接常的后缀字符标识了它的类型。
    • long:大写的L或小写的l(一般用大写的L,因为小写的l像数字1,容易造成混淆);
    • float:大写的F或小写的f。
    • double:大小的D或小写的d。
  • 十六进制整数:以0x或0X为前缀,后面跟随0~9或大写或小写的a~f来表示。
  • 八进制数:以0以为前缀,后面跟0~7的数字来表示。
  • 如果试图将一个变量初始化成超出自身表示范围的值,编译器就会报错,同时建议我们将值转化为int型。
  • c、c++或java中,二进制数没有直接常量表示法。可以用Integer或Long类的toBinaryString()静态方法显示结果。
    •  //十六进制
       int a = 0x2f;
       int b = 0X2F;
       //八进制
       byte c = 077;
       //long型
       long d = 100L;
       long e = 100l;
       long f = 100;
       //float型
       float g = 1;
       float h = 1F;
       float i = 1f;
       //double型
       Double j = 1D;
       Double k = 1d;
      
  • 指数计数法:用于表示指数。
    • 1.39e-43表示1.39X10-43
    • e代表10的幂次,见到e时请转换思维,它并不是自然对数的基数。
    • 编译器通常会将指数作为双精度数(double)处理,因此,定义float型指数时,必须在后面跟上大写或小写的F。
      •  float v = 1.39e-43f;
         double v1 = 1.39e-43;
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值