这一章之前我直接略过了,因为觉得这东西太基础,但是想想也不好,还是要稍微总结一下。

如果之前已经有编程基础,那么 Java 中的运算符并没有什么特别的,所以可以直接跳过。

开始使用运算符

Java 支持普通四则运算符:加减乘除 ,以及最重要的 赋值运算符 "=" 。

  • 四则运算符只能直接操作基本类型
  • 赋值运算符 "=" , 判断引用的 "==" , 和 "!=" 能操作所有对象
  • String 类支持 "+" 和 "+=" 运算符,

优先级

就跟初中学过的一样,当一个表达式中存才多个运算符时,计算是有优先级的:

  • 如果都是平级运算符 那么从左到右
  • 乘法和除法优先于加减
  • 优先计算被括号包裹的表达式

赋值

赋值运算符 "=" 代表着将右边的值赋给左边的变量。

右边可以是常量、变量、或者一个可产生值的表达式(比如一个方法)

基本类型的赋值是直接的,对象赋值则是将引用指向堆中内存的地址。

算数运算符

这里除了加减乘除,还有一个 % 取模,取模操作有点类似取余数,但是在对于负数取模时又和取余数不一样。

说实话取模我用的不多,没啥深入了解取余和取模的区别 这里有比较详细的介绍。

递增和递减

这个在循环中用的比较多,多是对 flag 变量进行修改,比如计数器之类的。

public class AutoInc {
    public static void main(String[] args) {
        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

如果递增定义在变量之前,会先对变量递增再完成后续表达式,反之则是先完成表达式再修改变量,递减亦然。

关系运算符

"==", "!=" ---> 对引用是否相等/不等 进行判断

">=" , "<=" 则是对数值进行的判断

判断对象是否相等

默认 "==" 和 "!=" 比较的是对象的内存地址是否相等,如果两个对象的内存地址一样,那么两个对象一定是相等的。

// operators/Equivalence.java
public class Equivalence {
    public static void main(String[] args) {
        Integer n1 = 47;
        Integer n2 = 47;
        System.out.println(n1 == n2);
        System.out.println(n1 != n2);
    }
}
// 输出结果 
true
false

下面来个对初学者有点迷惑的:

class Value {
    int i;
}

public class EqualsMethod2 {
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
    }
}
// 输出结果 false

因为这个你自己定义的类并没有重写 Object 类的 equals 方法,而 Object 类的equals 默认实现用的就是 "==" , 也就是比较两个对象是否内存地址一样,而 v1v2 是两个不同的对象,内存地址肯定不同,所以这里的 equals 返回 false

所以当我们需要在自定义的类中使用 equlas 方法之前,记得先去定义行为,比如根据特定的字段判断对象是否相同。

逻辑运算符

主要是 "&" 和 "|" ,"^|" 异或我在开发中几乎没用过,看源码好像也没见到过。

短路

我们在判断中可以使用短路来减少判断次数,也就是使用两个 "&&" 或者 "||" ,这样如果前一个判断结果不符合要求,就不需要再进行后面的判断了。

// operators / ShortCircuit.java 
// 逻辑运算符的短路行为
public class ShortCircuit {

    static boolean test1(int val) {
        System.out.println("test1(" + val + ")");
        System.out.println("result: " + (val < 1));
        return val < 1;
    }

    static boolean test2(int val) {
        System.out.println("test2(" + val + ")");
        System.out.println("result: " + (val < 2));
        return val < 2;
    }

    static boolean test3(int val) {
        System.out.println("test3(" + val + ")");
        System.out.println("result: " + (val < 3));
        return val < 3;
    }

    public static void main(String[] args) {
        boolean b = test1(0) && test2(2) && test3(2);
        System.out.println("expression is " + b);
    }
// 输出结果
test1(0)
result: true
test2(2)
result: false
expression is false

移位运算符

  • "<<" 左移 ,等效为 除以2
  • ">>" 右移 ,等效为 乘以2

一般在源码和类库中会看到这样的操作,因为效率更快,是直接从 数字的 bit 位开始对 0 和 1 进行操作,一般开发中用到的不多。

三元运算符

替代 if 表达式的一种运算符,其格式为:

布尔表达式 ? 值1 : 值2

  • 如果表达式为 true,则返回结果为 值1
  • false 返回 值2
public class TernaryIfElse {
// 这个布尔表示等效于 standardIfElse 方法中的 if 判断
static int ternary(int i) {
    return i < 10 ? i * 100 : i * 10;
}

static int standardIfElse(int i) {
    if(i < 10)
        return i * 100;
    else
        return i * 10;
}

    public static void main(String[] args) {
        System.out.println(ternary(9));
        System.out.println(ternary(10));
        System.out.println(standardIfElse(9));
        System.out.println(standardIfElse(10));
    }
}

类型转换

Java 可以将数据类型进行显示的转换,当低精度转为高精度没问题,如果将高精度强制转为低精度则可能导致信息的丢失。

public class Casting {
    public static void main(String[] args) {
        int i = 200;
        // 将 int 类型的数据提升为 long 类型的数据
        long lng = (long)i;
        lng = i; // 没有必要的类型提升
        long lng2 = (long)200;
        lng2 = 200;
        // 类型收缩,此时可能导致精度丢失,比如 lng2 存储的长度超过了 int 的上限,就会出现问题
        i = (int)lng2; // Cast required
    }
}

截断和舍入

Java 中的小数是被直接舍弃掉的

public class CastingNumbers {
    public static void main(String[] args) {
        double above = 0.7, below = 0.4;
        float fabove = 0.7f, fbelow = 0.4f;
        System.out.println("(int)above: " + (int)above);
        System.out.println("(int)below: " + (int)below);
        System.out.println("(int)fabove: " + (int)fabove);
        System.out.println("(int)fbelow: " + (int)fbelow);
    }
}
// 输出结果
(int)above: 0
(int)below: 0
(int)fabove: 0
(int)fbelow: 0

运算符总结

编程语言中最基础的一部分,如果是新手就跟着书上的例子练一下就行了,没有难度。

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

最是人间留不住,曾是惊鸿照影来。