java之复合运算符

赋值运算符
1.“+=”称为复合赋值运算符,类似的复合赋值运算符还有“?=”、“*=”、“/=”、“%=”、“&=”、“|=”、“^=”等。
2.引用类型可进行赋值的条件:在赋值运算符“=”左边的变量被显式声明的类型必须与“=”右边的变量的类型相同或有继承关系,否则编译出错。
3.注意:在赋值运算符的左边必须为变量,不能为任何表达式。
A mya=new A();
A myb=new A();
mya.setName("a");
myb.setName("b");
mya=myb;                     //将引用变量myb赋值给引用变量mya
System.out.println(mya.getName());                          //输出结果为: b
System.out.println(myb.getName());                         //输出结果为: b
mya.setName("c");               //调用引用变量mya所引用对象的setName()方法,设置成员变量值为"c"
System.out.println(mya.getName());                          //输出结果为: c
System.out.println(myb.getName());                         //输出结果为: c
从结果可以看出,通过“mya=myb”赋值操作后,引用变量mya与myb引用了同一个对象,所以通过其中任何一个变量来操作被引用的对象都会影响到另一个变量所引用的对象。
A mya=new A();
A myb=new A();
mya.setName("a");
myb.setName("b");
mya=myb;
System.out.println(mya.getName());                   //输出结果为: b
System.out.println(myb.getName());                  //输出结果为: b
mya=null;                                                //将变量mya赋值为null, 则mya不引用任何对象


将一个整数除以0或除以0求余的运算
当进行一个整数除以0或除以0求余运算时,虽然可以通过编译,但在运行时会抛出java.lang.ArithmeticException异常,例如:
int i1=11/0;                               //编译成功, 但运行时抛出异常
int i2=9%0;                               //编译成功, 但运行时抛出异常
System.out.println(i1);
System.out.println(i2);
以上代码运行时抛出java.lang.ArithmeticException异常。


当浮点型数据进行运算时,计算机计算出的小数点后的n位,与实际的数值会有一定的误差,它只能尽量地去接近实际值。
例如,计算float型数据4.0减去浮点型数据2.9的结果,在数学计算中该结果为1.1,但计算机计算出的结果只能尽量地去接近1.1。
float f=4.0f-2.9f;
System.out.println(f);                         //输出结果为: 1.0999999
在浮点型数据的算术运算中,若进行一个浮点型数据除以0或除以0求余的运算,在运行时并不会抛出异常,而会得到表示无穷大、无穷小或为NaN的特殊值:正浮点数除以0,结果为Infinity,表示无穷大;负浮点数除以0,结果为-Infinity,表示无穷小;浮点数除以0求余,结果为NaN。
例如:
float f1=1.234f/0;                            //计算正浮点数除以0
float f2=-5.678f/0;                           //计算负浮点数除以0
float f3=1.234f%0;                          //计算正浮点数除以0求余
float f4=-5.678f%0;                         //计算负浮点数除以0求余
System.out.println(f1);                      //输出结果为: Infinity
System.out.println(f2);                     //输出结果为: -Infinity
System.out.println(f3);                     //输出结果为: NaN
System.out.println(f4);                     //输出结果为: NaN

1.“==”运算符
比较基本数据类型变量
当两个基本数据类型的操作元通过“= =”运算符比较是否相等时,比较的是这两个操作元的值是否相等,若相等结果为true,否则为false,在比较时不考虑操作元的数据类型。
例如:
int i=98;
int j=-98;
float f=98.0f;
System.out.println(i==j);                     //输出结果为: false
System.out.println(i==f);                     //输出结果为: true
System.out.println(i=='b');                          //输出结果为: true
System.out.println(j==-'b');                        //输出结果为: true
比较引用类型变量
当两个引用类型的变量通过“==”运算符比较是否相等时,比较的是这两个变量是否引用了同一个对象,若是结果为true,否则为false。
例如:
Integer num1 = new Integer(100);              //创建一个Integer对象, 并通过num1变量进行引用
Integer num2 = new Integer(100);              //创建另一个Integer对象, 并通过num2变量进行引用
System.out.println((num1==num2);            //输出结果为: false
System.out.println(num1!=num2);              //输出结果为: true
下面将以上代码进行修改:
Integer num1 = new Integer(100);
Integer num2 = new Integer(200);
num1=num2;                             //将num2引用的对象赋值给num1, 使得这两个变量引用同一个对象
System.out.println(num1==num2);                     //输出结果为: true
System.out.println(num1!=num2);                     //输出结果为: false
Integer num1=80;                                      //将自动进行80转换为Intege对象的装箱操作
Integer num2=80;                                      //将自动进行80转换为Intege对象的装箱操作
System.out.println(num1==num2);                     //输出结果为: true
这两段代码几乎是一样的,只不过改动了后者的数值,为什么返回的结果却是true呢?这是因为Java包装类在进行自动装箱、拆箱时隐藏了一些细节上的操作。
Java在执行包装类的自动装箱功能时,对于?128到127之间的整数(包括?128与127)被装箱为Integer对象后,该对象会被另一个对该整数进行自动装箱的操作重复使用,也就是说多次对同一个?128~127范围内的整数进行Integer装箱的操作,使用的都是第一次进行装箱操作时生成的对象,所以在进行“==”比较时,返回的结果是true。如果对超过这个范围内的整数进行装箱操作,那么对该整数的每次的Integer装箱操作都会生成一个新的Integer对象,所以在进行“==”比较时,比较的是不同的对象,返回的结果为false。

在比较字符串是否相等时,为了能够正确得到预期的运行结果,应该采用equals()方法进行比较。例如:
String name="mingri";                                       //将一个String型字面常数赋给变量name
if(name=="mingri")
    System.out.println("登录成功!");
else
    System.out.println("登录失败!");

虽然上述代码的运行结果与预期的相同,但如果将代码中的第一行进行如下修改:
String name=new String("mingri");
则将会得到“登录失败!”的运行结果。

在自定义的类中也可以重写Object类的equals()方法,重新定制比较规则。例如创建了一个Student类用来封装学生信息,其中包含一个String型的number属性,该属性存储学生学号。如果想定义两个Student类对象的number属性内容相同,则表示这两个对象存储的是同一个学生的信息的比较规则,通过equals()方法实现时,就可进行如下定义:
public class Student {
    private String number;                              //用来存储身份证号码
    public Student(String number){                         //构造函数
        this.number=number;
    }
    public boolean equals(Object obj){                           //重写equals()方法
        if(this==obj)
              return true;
        if(obj instanceof Student){
              if((this.number).equals(((Student)obj).number))

            return true;
        }
        return false;
    }
}
然后通过构造函数创建两个Student类对象,它们的number属性都被赋值为字符串“1001”,并分别通过变量st1与st2引用这两个对象,则应用equals()方法比较这两个对象的结果为true。
Student st1=new Student("1001");
Student st2=new Student("1001");
System.out.println(st1==st2);                            //数据结果为: false
System.out.println(st1.equals(st2));                    //输出结果为: true

 
逻辑运算符只能对布尔型数据进行操作,所以返回的结果也是布尔类型的值。Java语言中的逻辑运算符包括逻辑与“&&”、逻辑或“||”和逻辑非“!”3种。
Java又将逻辑运算符分为了“短路”和“非短路”运算符。
例如:定义两个int型变量a和b,并分别赋值为整数1和2,将两个关系表达式进行“&&”逻辑与运算,其中表达式“(a=9+3)<10”的值为false,表达式“(b=8-3)>4”的值为true,所以这两个表达式进行逻辑与运算的结果为false。但该例的主要目的是为了证明是否执行了表达式“(b=8-3)>4”,所以可以通过输出变量a和b的值来查看。
int a=1;
int b=2;
boolean result=((a=9+3)<10)&&((b=8-3)>4);
System.out.println("result="+result);
System.out.println("a="+a);
System.out.println("b="+b);
如果上述代码执行了表达式“(b=8-3)>4”,那么b的值应为5,而实际的运行结果如下:
result=false
a=12
b=2
“b=2”说明没有执行表达式“(b=8-3)>4”,下面将“&&”运算符修改为“&”。
boolean result=((a=9+3)<10)&((b=8-3)>4);
再次运行的结果如下:
result=false
a=12
b=5
“b=5”说明执行了表达式“(b=8-3)>4”,所以逻辑运算符“&&”是“短路”运算符,而“&”是“非短路”运算符。“短路”运算符还包括“||”,同样,“|”属于“非短路”运算符。
在实际应用时,更多的应用“短路”逻辑运算符,因为使用“短路”运算符算在一些情况下只需计算其中一个表达式的值就可得到整个表达式的结果,缩短了执行时间,提高了执行速度。例如“true||(45328/45+3455.33)>(99*23+98.12)”,已知道左边的值为true,则整个表达式的值为true,所以不需要再执行右边的表达式。
使用“短路”逻辑运算符有助于提高程序代码的安全性,例如:判断用户是否输入了数值,可通过如下编码:
String name=null;
//判断name不等于null并且不等于空,当name等于null时, 不会执行name.equals("")方法
if(name!=null&&!name.equals(""))
    System.out.println("用户名: "+name);
else
    System.out.println("请输入用户名!");
代码中表达式“!name.equals("")”进行的是逻辑非的运算,可以理解为变量name的值是否不等于空,若返回值为true,则“name.equals("")”值为false,说明name的值不为空。
代码运行结果如下:
请输入用户名!
若使用“非短路”逻辑与运算符“&”进行判断:
String name=null;
//判断name不等于null并且不等于空, 但name等于null时, 还会执行name.equals("")方法
if(name!=null&!name.equals(""))
    System.out.println("用户名: "+name);
else
    System.out.println("请输入用户名!");
则会抛出java.lang.NullPointerException空指针异常。因为name没有引用任何对象,所以name.equals("")将抛出异常错误。


1.自动递增、递减运算符
int num1=3;
int num2=3;
int a=2+(++num1);                          //先将变量num1加1, 然后再执行"2+4"
int b=2+(num2++);                          //先执行"2+3"; 然后再将变量num2加1
System.out.println(a);                         //输出结果为: 6
System.out.println(b);                         //输出结果为: 5
System.out.println(num1);                   //输出结果为: 4
System.out.println(num2);                   //输出结果为: 4
自动递增、递减运算符的操作元只能为变量,不能为字面常数和表达式,且该变量类型必须为整型、浮点型或Java包装类型。例如:++1、(num+2)++都是不合法的。

2.“?:”三元运算符
应用“?:”三元运算符的表达式的语法形式如下:
布尔表达式 ? 表达式1 : 表达式2
其运算规则为:若“?”左边布尔表达式的值为true,则整个表达式的值为表达式1的值,否则为表达式2的值。例如:
int store=12;
System.out.println(store<=5?"库存不足!":"库存量:"+store);      //输出结果为"库存量: 12"
以上代码等价于如下的if-else语句:
int store=12;
if(store<=5)
    System.out.println("库存不足!");
else
    System.out.println("库存: "+store);
读者应注意的是,对于“?:”三元运算表达式中的表达式1与表达式2并不会都被执行,例如:
int num1=3;
int num2=3;
int c='A'=='a'?(num1+=10):(num2+=10);
System.out.println(c);                         //输出结果为: 13
System.out.println(num1);                   //输出结果为: 3
System.out.println(num2);                   //输出结果为: 13
int a=3;
int b=3;
int c=a+++b;                             //根据运算符的优先级"++"优先于"+", 所以c=(a++)+b
System.out.println(c);                       //输出结果为: 6
boolean e=!false||true;              //先来执行"!false", 再进行逻辑或运算
boolean f=!(false||true);                  //先来执行"false||true", 再进行逻辑非运算
System.out.println(e);                       //输出结果为: true
System.out.println(f);                       //输出结果为: false
int g=3;
System.out.println(g+=2>4);       //编译出错, 因为运算符">"优先于"+=", 所以先来执行"2>4",
                                             //再来执行"g+=false", 而布尔值不能参与算术运算,因此编译出错
System.out.println((g+=2)>4);           //g值为5, 输出结果为: true
int n1=3;
int n2=3;
int k=20;
System.out.println(n1*=10+k);          //根据赋值运算符的结合性,
                                             //等价于"n1=n1*(10+20) ", n1值为90, 输出结果为: 90
System.out.println((n2*=10)+k);        //等价于" (n2=n2*10)+k", n2值为30, 输出结果为: 50

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值