重温Java(三):运算符、优先级和数据转换

本章目录:
1.运算符(operator)
2.运算符优先级的问题
3.数值类型之间的转换

1.运算符(operator)

计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操作变量。
在这里插入图片描述
1.1 算术运算符
在Java中的算术运算符 +、-、*、/、%表示加、减、乘、除、取模,都属于二元运算符,二元运算符指的是需要两个操作数才能完成运算的运算符。其中的%是取模运算符,就是我们常说的求余数操作。当参与/运算的两个操作数都是整数时,表示整数除法;否则,表示浮点数除法。例如,15/2=7,15.0/2=7.5。

示例:

public static void main(String[] args) {
        int result = 1 + 2;
        // result is now 3
        System.out.println("1 + 2 = " + result);
        int original_result = result;

        result = result - 1;
        // result is now 2
        System.out.println(original_result + " - 1 = " + result);
        original_result = result;

        result = result * 2;
        // result is now 4
        System.out.println(original_result + " * 2 = " + result);
        original_result = result;

        result = result / 2;
        // result is now 2
        System.out.println(original_result + " / 2 = " + result);
        original_result = result;

        result = result + 8;
        // result is now 10
        System.out.println(original_result + " + 8 = " + result);
        original_result = result;

        result = result % 7;
        // result is now 3
        System.out.println(original_result + " % 7 = " + result);
    }

运行结果:
在这里插入图片描述
+还可以连接两个字符串,使其生成一个字符串,例如:

    public static void main(String[] args) {
        String firstString = "This is";
        String secondString = " a concatenated string.";
        String thirdString = firstString+secondString;
        System.out.println(thirdString);
    }

运行结果:

This is a concatenated string.

注意:整数被0除时会产生异常,而浮点数被0除将会得到无穷大或NaN结果。

二元运算符的运算规则
整数运算:

  1. 如果两个操作数有一个为long,则结果也是long。
  2. 没有long时,结果为int。即使操作数全为short、byte,结果也是int。

浮点运算

  1. 如果两个操作数有一个为double,则结果为double。
  2. 只有两个操作数都是float,则结果才为float。

取模运算
操作数可以为浮点数,一般使用整数,结果是“余数”,余数的符号和左边的操作数相同;例如:7%3=1,-7%3=-1,7%-3=1。

一元运算符
++ 和 – 属于一元运算符,该类运算符只需要一个操作数。
示例:

int a = 3;
int b = a++; // a先取值赋给b,后a在自增,所以b=3
System.out.println("a = " + a + "\t b = " + b);
// a = 4    b = 3

a = 3;
b = ++a; // a先自增,后取值赋给b,所以b=4
System.out.println("a = " + a + "\t b = " + b);
// a = 4    b = 4

int c = 7;
int d = 7;
int m = 2 * ++c; // m = 16 c = 8
int n = 2 * d++; // n = 14 d = 8

注:自增和自减运算符改变了变量的值,所以它的操作数不能是数值。例如,4++就是一条非法语句。

注意区分++、–的位置,如果是在变量之前,则先自增或自减,后取值;如果是在变量之后,则先取值,后自增或自减。不建议在表达式的内部使用++、–,因为这样写代码会令人困惑,并会不小心产生烦人的bug。

Java官方教程中还指出+、-、!三个一元操作符。
在这里插入图片描述
需要注意的是此处的+和-是用来标识正数和负数的;!表示逻辑非运算。
示例:

public static void main(String[] args) {
        int result = +1;
        // result is now 1
        System.out.println(result);

        result--;
        // result is now 0
        System.out.println(result);

        result++;
        // result is now 1
        System.out.println(result);

        result = -result;
        // result is now -1
        System.out.println(result);

        boolean success = false;
        // false
        System.out.println(success);
        // true
        System.out.println(!success);
    }

1.2 赋值及其扩展赋值运算符
赋值语句就是将其右侧的值或表达式赋值给左侧的变量。
在这里插入图片描述
示例:

int a = 3;
int b = 4;
a += b; // 相当于 a = a + b;
System.out.println("a = " + a + "\t b = " + b);
// a = 7    b = 4

a = 3;
a *= b + 3; // 相当于a = a * (b + 3);
System.out.println("a = " + a + "\t b = " + b);
// a = 21   b = 4

1.3 关系运算符
关系运算符就是用来判断左右操作数大小关系的运算符,其结果是布尔值:true/false。
在这里插入图片描述
示例:

public static void main(String[] args) {
        int value1 = 1;
        int value2 = 2;
        if (value1 == value2) {
            System.out.println("value1 == value2");
        }
        if (value1 != value2) {
            System.out.println("value1 != value2");
        }
        if (value1 > value2) {
            System.out.println("value1 > value2");
        }        
        if (value1 >= value2) {
            System.out.println("value1 >= value2");
        }
        if (value1 < value2) {
            System.out.println("value1 < value2");
        }
        if (value1 <= value2) {
            System.out.println("value1 <= value2");
        }
    }

运行结果:

value1 != value2
value1 < value2
value1 <= value2

注意事项
1.=是赋值运算符,而真正的判断两个操作数是否相等的运算符是==;
2.==、!=是所有(基本和引用)数据类型都可以使用的
3.>、>=、<、<=仅针对数值类型(byte、short、int、long,float、double,以及char)

instanceof 类型比较符
instanceof运算符将对象与指定类型进行比较。可以使用它来判断对象是类的实例、子类的实例还是实现特定接口的类的实例。
示例:

class InstanceofDemo {
    public static void main(String[] args) {

        Parent obj1 = new Parent();
        Parent obj2 = new Child();

        System.out.println("obj1 instanceof Parent: "
            + (obj1 instanceof Parent));
        System.out.println("obj1 instanceof Child: "
            + (obj1 instanceof Child));
        System.out.println("obj1 instanceof MyInterface: "
            + (obj1 instanceof MyInterface));
        System.out.println("obj2 instanceof Parent: "
            + (obj2 instanceof Parent));
        System.out.println("obj2 instanceof Child: "
            + (obj2 instanceof Child));
        System.out.println("obj2 instanceof MyInterface: "
            + (obj2 instanceof MyInterface));
        System.out.println("null instanceof Parent: "
                + (null instanceof Parent));
        System.out.println("null instanceof Child: "
                + (null instanceof Child));
        System.out.println("null instanceof MyInterface: "
                + (null instanceof MyInterface));
    }
}

class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}

运行结果:

obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: true
null instanceof Parent: false
null instanceof Child: false
null instanceof MyInterface: false

注意:使用instanceof关系运算符时,需要注意null不是任何类或接口的实例。

1.4 逻辑运算符
Java中的逻辑运算的操作数以及运算结果都是boolean值。在这里插入图片描述
短路与和短路或,从左至右计算,如果只通过运算符左边的操作数就能确定该逻辑表达式的值,则不会继续计算运算符右边的操作数,提高效率。

示例:

// 1 > 2 的结果为false,那么整个表达式的结果就是false;将不再计算 2 > (3 / 0)
boolean c = 1 > 2 && 2 > (3 / 0);
System.out.println(c); // false

// 1 > 2 的结果为false,那么整个表达式的结果虽是false;还会计算 2 > (3 / 0)
// 0不能被整除,会报异常
boolean d = 1 > 2 & 2 > (3 / 0);
System.out.println(d);

1.5 位运算符
位运算指的是进行二进制位的运算
在这里插入图片描述
示例:

int a = 3 * 2 * 2;
int b = 3 << 2; // 相当于3 * 2 * 2
System.out.println("a = " + a + "\t b = " + b); // a = 12   b = 12

int c = 12 / 2 / 2;
int d = 12 >> 2; // 相当于12 / 2 / 2
System.out.println("c = " + c + "\t d = " + d); // c = 3    d = 3

雷区:

  1. & 和 | 既是逻辑运算符,也是位运算符。如果两侧操作数都是boolean类型,就作为逻辑运算符。如果两侧是整数类型,就是位运算符。
  2. 不要把^当做数学运算的“乘方”,而是“位的异或”操作。

1.6 字符串连接符
“+”运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换成字符串,然后再进行连接。

示例:

int num = 10;
System.out.println("num = " + num); // num = 10

int a = 10;
int b = 20;
System.out.println(a + b + "万元"); // 30万元

1.7 条件运算符
Java支持三元运算符? :

语法格式:x ? y : z

其中x为boolean类型表达式,先计算x的值,若为true,则整个运算的结果为表达式y的值,否则整个运算结果为表达式z的值。

示例:

int score = 80;
int x = -100;
String type = score < 60 ? "不及格" : "及格";
int flag = x > 0 ? 1 : (x == 0 ? 0 : -1);
System.out.println("type = " + type); // type = 及格
System.out.println("flag = " + flag); // flag = -1
2. 运算符优先级的问题 在这里插入图片描述

建议:

  1. 无需刻意死记硬背优先级,表达式里面优先使用小括号来组织
  2. 逻辑与、逻辑或、逻辑非的优先级需要牢记!(逻辑非>逻辑与>逻辑或)例如: a || b && c 的运算结果是:a || (b && c),而不是(a || b) && c

Java官网教程练习题

3.数值类型之间的转换

• 在赋值运算或算术运算时,要求数据类型相同,否则要进行类型转换
• 转换方式:自动转换 和 强制转换
• 除boolean类型外,所有的基本数据类型因为各自的精度不同,赋值时都要考虑这个问题
• 除boolean类型外,所有的基本数据类型包括:整型,浮点型,字符型。

数值类型之间自动转换图
在这里插入图片描述

图中6个实心箭头,表示无信息丢失的转换;有3个虚箭头,表示可能有精度损失的转换。

数值类型进行二元操作时,先要将两个操作数转换成同一种类型,然后再计算。规则如下:

如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型;
否则,如果其中一个操作数是float类型,另一个操作数就会转换为float类型;
否则,如果其中一个操作数是long类型,另一个操作数就会转换为long类型; 否则,两个操作数都将被转换为int类型;

类型转换的方向
• 低------------------------------------------------------------->高
• byte —> short,char—>int —>long—>float —>double

注:可以将整型常量直接赋值给byte、short、char等类型变量,而不需要进行强制类型转换,只要常量值不超过对应数据类型的范围即可。

自动转换的特例:

short x = 12; //合法
short y = 1234567; //非法 ,已经超出short的范围

强制转换
前面已经介绍了自动转换,例如int类型自动转换为double类型。但是有时候也需要 double类型转换为int类型,在Java中称为强制类型转换(cast),又称作造型。当然强制转换可能会有信息丢失,也就是精度降低或者溢出。

语法格式:(type)var

其中type表示var将要转换成的目标数据类型。

double x = 9.9997;
int y = (int) x;
System.out.println("y = " + y); // y = 9

强制类型转换通过截断小数部分将浮点值转换成整型。

操作比较大的数,需要留意是否溢出,尤其是整数操作时。

 int money = 1000000000; // 10亿
 int years = 20;
 int total = money * years; // 返回负数,超过了int的范围
 System.out.println("total = " + total);

 long total1 = money * years; // 返回负数,整型默认是int类型,因此计算结果转成int值(此时已经超出int范围),赋值时进行转换成long
 System.out.println("total1 = " + total1);

 long total2 = money * ((long)years); // 返回正确结果:先将一个操作数转换成long,整个表达式就会全部使用long计算
 System.out.println("total2 = " + total2);
//        total = -1474836480
//        total1 = -1474836480
//        total2 = 20000000000

总结
• =右侧:所有变量先转换为字节数最多的数据类型,再计算
• =两侧:左侧宽度>右侧宽度 自动转换
• 左侧宽度<右侧宽度 强制转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值