第3章-运算符

Think in java 读书笔记

pikzas

2019.03.03

第3章-操作符

知识点

算数运算符

"+" 在处理字符串时候的特殊处理

常规的算数运算符有加减乘除取余赋值等(+-*/%=),这些操作符对于所有的基本数据类型都是可以直接使用的,但是对于对象还能有判定内存地址是否相等,是否不等,赋值(==,!=,=)操作符可以用。对于String这个特殊的引用对象类型,还可以使用拼接符(+),这是Java提供的一个语法糖,反编译字节码后,会发现”+“号会被StringBuffer的append方法代替。

"=" 在对象赋值过程中的特殊处理(别名现象)

发生这种现象是因为Java是值传递的,
对于基本数据类型,一个变量其实是指向堆栈中特定的值,在进行a=b这种赋值操作的时候,实际上是将b的值拷贝给了a变量。
对于引用数据类型,m=n这个操作,是将变量n所指向的对象的地址赋值给了m,这时候如果对m,n所指向的是同一个内存地址的同一个对象,无论是通过m还是n对对象有任何改变,所有指向该对象的引用(即变量)都会将这次的改变体现出来。

class Tank{
    int level;
}

public class Demo{
    Tank t1 = new Tank();
    Tank t2 = new Tank();
    t1.level = 12;
    t2.level = 34;
    print("--1--"+t1.level+"---"+t2.level);
    t1 = t2; // t1 变量的指针指向了t2 的所指向的那个对象
    t1.level = 56; // 通过t1 对对象作出改变
    print("--2--"+t1.level+"---"+t2.level);
}

// 打印结果
// --1--12---34
// --2--56---56

别名现象也会出现在方法调用上


public class Test {

    public static void f(int x) {
        x = 12;
    }

    public static void f2(String args) {
        args = "1234";
    }

    public static void f3(Bean bean) {
        bean.x = 123;
    }

    public static void main(String[] args) {
        int y = 44;
        f(y);
        System.out.println(y);
        String str = "xxx";
        f2(str);
        System.out.println(str);
        Bean bean = new Bean();
        bean.x = 111;
        f3(bean);
        System.out.println(bean.x);
    }
}

class Bean{
    public int x;
}

// 输出结果为
44
xxx
123  //为什么这个值发生了变化,而上面两个没有呢

除运算(/)在java中返回的值只有整数部分,不会四舍五入。

自动递增和递减

  • 对于前缀递增和递减(++a或--a)会先执行运算,在生成值
  • 对于后缀递增和递减(a++或a—-)会先生成值,在执行运算
class Demo{
    public static void main(String[] args){
        int i = 1;
        System.out.println("i: " + i); //1
        System.out.println("++i:" + ++i); //2
        System.out.println("i++:" + i++); //2
        System.out.println("i: " + i); //3
        System.out.println("--i:" + --i); //2
        System.out.println("i--:" + i--); //1
    }
}

关系操作符

关系操作符返回的结果是布尔值 true 或者 false

所有的运算符包含 大于(>)、小于(<)、大于或等于(>=)、小于或等于(<=)、等于(==)、不等于(!=)。以上运算符可以作用在除布尔值以外的所有对象上。

  • 布尔值只有true 或者 false 不存在谁比谁大。
  • 以上运算符如果作用在引用数据类型的时候,比较的是其地址,如果需要比较对象的"值",则需要对该对象重载equals方法。默认的基础数据类型的包装类,都有做重写equals处理。
public class TestOne{
    public static void main(String[] args) {
        Integer i1 = new Integer(1);
        Integer i2 = new Integer(1);
        System.out.println(i1 != i2); //true
        System.out.println(i1 == i2); //false
        System.out.println(i1 > i2);  //false
        System.out.println(i1 < i2);  //false
        System.out.println(i1.equals(i2)); //true
    }
}

逻辑运算符

由于java是强类型语言,所以在进行逻辑运算的时候,参与运算的参数必须都是布尔类型,不能像js那样运行(123 && 123) = true。注意逻辑运算过程中的短路,一旦能确定运算结果,表达式就会停止运算再往后的表达式。

直接常量

一般我们在程序里都是用的数字都是十进制的,在指定情况下,也可以用二进制,八进制或者十六进制。

class Demo{
    int i = 0x2f;  // 0x或者0X 开头表示该数字为十六进制 
    int j = 0177;  // 0 开头表示该数字为八进制
    int m = 0b101; // 0b 开头表示该数字为二进制
    int n = 100; // 默认情况下表示为十进制
    
    long l = 123123123;
    long l1 = 234234234L;
    long l2 = 345345345L;
    
    float f = 123.234;
    float f1 = 12.333f;
    float f2 = 23.555F;
    
    double d1 = 1.234d;
    double d2 = 2.345D;
    
}

16进制在表示一些特殊数字的时候比较方便,如char类型的占有2byte=16bits位,取值范围为 0 - 216-1,2的8次方✖️2的8次方-1=256×256-1=65535-1=0xffff-1

不同进制转换方法,假设数字是mab这样的格式 如果m=0x 代表这是16进制数字 那么将16进制的ab转换为10进制为: a×16(2-1) + b×16(1-1)

位操作符

位操作符号有 与(&)、或(|)、异或(^)、非(~)

先将数字转换为二进制,然后从右向左逐位取一位运算,将1看为true,0看为false。则位运算符与逻辑运算符类似,^可以看成如果两位相同,则取0,否则取1.

class Demo{
    public static void main(String[] args){
      System.out.println(1&1);  // 1
      System.out.println(1&0);  // 0
      System.out.println(0&1);  // 0
      System.out.println(0&0);  // 0
      
      System.out.println(1|1);  // 1
      System.out.println(1|0);  // 1
      System.out.println(0|1);  // 1
      System.out.println(0|0);  // 0
      
      System.out.println((0b11)^(0b11));  // 0
      System.out.println((0b10)^(0b10));  // 0
      System.out.println((0b11)^(0b10));  // 1
      System.out.println((0b11)^(0b00));  // 3
      
      // ~按位去反 输入0得1 输入1得0
    }
}

位移运算符

有符号的左移、右移(<<,>>)和无符号的右移(>>>)

类型转换

再将变量做类型转换的时候,若从较小的类型转换成较大的类型的时候,可以自动实现。反之则需要显式的申明,表明你已经知道可能存在的信息丢失的风险。

在将double 或者float 数据转换为int的时候,总是取数轴上离零点最近的那个值 (int)(29.5) = 29 、(int)(-29.5) = -29

如果想要实现四舍五入操作,需要使用Math.round(); 总是往大了转。

class Demo{
    public static void main(String[] args){
        System.out.println(Math.round(-29.3)); //-29
        System.out.println(Math.round(-29.5)); //-29
        System.out.println(Math.round(-29.7)); //-29
        System.out.println(Math.round(29.3));  //29
        System.out.println(Math.round(29.5));  //30
        System.out.println(Math.round(29.7));  //30
    }
}
posted @ 2020-01-05 23:36  pikzas  阅读(200)  评论(0编辑  收藏  举报