Thinking in Java

3. 操作符

3.1 静态导入

  • 静态导入:方法中调用静态导入的其他类中的静态方法
package com.one;
public class Print {
    public static void print(String s){
        System.out.println(s);
    }
}
package com.one;
// 静态导入方法
import static com.one.Print.*;
public class TestPrint {
    public static void main(String[] args) {
        System.out.println("Nomal Print");
        // 静态导入的方法输出
        print("Simple Print");
    }
}

3.2 使用Java操作符

  • 副作用:操作符改变操作数本身的值

String类支持"+"和"+="

3.3 优先级

  • 优先级顺序
    • 先乘除后加减
    • 用括号明确计算顺序

3.4 赋值

  • 赋值:使用操作符"="

  • 赋值分类

    • 基本类型赋值:直接将内容复制到另一个地方

    • 对象类型赋值:将“引用”从一个地方复制到另一个地方(一个对象对应多个引用,一个引用可能有0或1个对象),类似指针,由于原来的指针指向新的对象,所以原来的对象将被垃圾回收器清理,具体可见以下实现

      class Tank{
        int level;
      }
      public class Assignment{
        public static void main(String[] args){
          // 赋值前
          Tank t1 = new Tank();
          Tank t2 = new Tank();
          t1.level = 9;
          t2.level = 47;
          print(t1+","+t2);
          // 第一次赋值
          t1 = t2; 
          print(t1+","+t2);
          // 第二次赋值
          t1.level = 22;
          print(t1+","+t2);
        }
      }
      /*
      output:
      9,47
      47,47
      22,22
      */
      
  • 别名现象解析

    • 代码片段(见赋值分类的对象类型赋值)

    • 原理分析

      • 第一次赋值是将t2的指向修改为与t1一致,同时指向同一个对象,因为t1和t2都是引用

      • 第二次赋值是将t1和t2指向的同一个对象中的level值修改了

        [图片上传失败...(image-83be4-1563342666109)]

3.5 算术操作符

  • 操作符种类

    • 加号+、减号-、除号/、乘号*,取模%
    • 整数除法会直接去掉结果的小数位,不会四舍五入
  • Random方法

    • Random为生成伪随机数的类,使用nextInt()/nextFloat()方法获取随机数

    • 如果种子参数相同,则生成的随机数也相同,见下方

      package com.four;
      import java.util.Random;
      public class TestRandom {
          public static void main(String[] args) {
                      // 种子数相同      
              Random random1 = new Random(10);
              Random random2 = new Random(10);
              int i = random1.nextInt();
              int j = random2.nextInt();
              System.out.println("i="+i);
              System.out.println("j="+j);
          }
      }
      /* output:
      i=-1157793070
      j=-1157793070
      */
      

3.5.2 一元加、减操作符

  • 一元减号:转变数据的符号,或修改数据类型

  • 一元加号:将数据类型修改为int类型

    package com.four;
    public class TestAdd {
        public static void main(String[] args) {
            int i = 1;
            char j = 'c';
            short k = 5;
            System.out.println(i);
            System.out.println(j);
            System.out.println(k);
            System.out.println("添加加号");
            System.out.println(+i);
            System.out.println(+j);
            System.out.println(+k);
            System.out.println("添加减号");
            System.out.println(-i);
            System.out.println(-j);
            System.out.println(-k);
        }
    }
    /* output
    1
    c
    5
    添加加号
    1
    99
    5
    添加减号
    -1
    -99
    -5
    */
    // /Users/toyz/Package/Note/Thinking in Java/Practice/Operators/src/com/four/TestAdd.java
    

3.6 自动递增和递减

  • 分类

    • 前缀递增、前缀递减:先执行运算,后生成值

    • 后缀递增、后缀递减:先生成值,后执行运算

      package com.four;
      import static util.Print.*;
      public class TestIncreasing {
          public static void main(String[] args) {
              int i = 1;
              int j = i;
              print("i = "+i);
              // 前缀递增
              j = ++i;
              print("前缀递增后");
              print("i = "+i);
              print("j = "+j);
              i = 1;
              j = i;
              // 前缀递减
              j = --i;
              print("前缀递减后");
              print("i = "+i);
              print("j = "+j);
              i = 1;
              j = i;
              // 后缀递增
              j = i++;
              print("后缀递增后");
              print("i = "+i);
              print("j = "+j);
              i = 1;
              j = i;
              // 后缀递减
              j = i--;
              print("后缀递减后");
              print("i = "+i);
              print("j = "+j);
              i = 1;
              j = i;
          }
      }
      /* output
      i = 1
      前缀递增后
      i = 2
      j = 2
      前缀递减后
      i = 0
      j = 0
      后缀递增后
      i = 2
      j = 1
      后缀递减后
      i = 0
      j = 1
      */
      // /Users/toyz/Package/Note/Thinking in Java/Practice/Operators/src/com/four/TestIncreasing.java
      

3.7 关系操作符

  • 分类
    • 大于、小于、大于等于、小于等于、等于(==)、不等于(!=)
    • 等于和不等于适用所有基本数据类型,其他比较符不使用boolean类型

3.7.1 对象的等价性

  • ==和!=比较的是对象的引用

    package com.five;
    
    public class TestEquals {
        public static void main(String[] args) {
            // 使用==比较 基本数据类的相同内容的不同对象
            Integer n1 = new Integer(47);
            Integer n2 = new Integer(47);
            System.out.print("使用==比较 相同内容的不同对象:");
            System.out.println(n1 == n2);
    
            // 使用equals比较 基本数据类的相同内容的不同对象
            System.out.print("使用equals比较 相同内容的不同对象:");
            System.out.println(n1.equals(n2));
    
            // 使用==比较 自定义类的相同内容的不同对象
            Dog dog1 = new Dog();
            dog1.setName("spot");
            dog1.setSays("Ruff!");
            Dog dog2 = new Dog();
            dog2.setName("spot");
            dog2.setSays("Ruff!");
            System.out.print("使用==比较 自定义类的相同内容的不同对象:");
            System.out.println(dog1 == dog2);
    
            // 使用equals比较 自定义类的相同内容的不同对象
            System.out.print("使用equals比较 相同内容的不同对象:");
            System.out.println(dog1.equals(dog2));
        }
    }
    /* output
    使用==比较 相同内容的不同对象:false
    使用equals比较 相同内容的不同对象:true
    使用==比较 自定义类的相同内容的不同对象:false
    使用equals比较 相同内容的不同对象:false
    */
    // /Users/toyz/Package/Note/Thinking in Java/Practice/Operators/src/com/five/TestEquals.java
    
  • 总结

    • == 对于基本数据类型,是比较值;对于引用数据类型,是比较地址
    • equals 对于引用的基本数据类型的比较生效,适合比较对象内容,而非比较对象的引用

3.8 逻辑操作符

  • 分类
    • 与(&&)、或(||)、非(!)
    • 以上三种只能应用于布尔值
    • 在String值的地方使用布尔值,布尔值会自动转换成适当的文本

3.8.1 短路

  • 定义:当能够确定一个表达式的值,就不计算余下的部分

  • 演示过程:当判断到(j<2)时为false时,程序不会执行后续判断,直接输出false

    package com.seven;
    import static util.Print.*;
    public class ShortCircuit {
        public static void main(String[] args) {
            int i = 1;
            int j = 2;
            int k = 3;
            print("res:"+((i<2)&&(j<2)&&(k<2)));
        }
    } 
    

3.9 直接常量

直接常量的后缀字符标注了类型

  • 常用类型
    • L代表long
    • F代表Float
    • D代表Double
    • 十六进制数字:以前缀0x,后面跟随0~9或小写的a~f来表示
    • 八进制数字:以前缀0,后面跟随0~7数字来表示

3.9.1 指数计数法

程序设计时使用e代表“10的幂次”,但是在科学和工程领域,e代表自然对数的基数

3.10 按位操作符

  • 运算方式

    • &、|、^、~
    • 与、或、异或、取反
    • **异或:相同则为零,不同则为1 **
  • 运算规则

    1. &: 1&1=1 , 1&0=0 , 0&1=0 , 0&0=0
    2. |: 1|1=1 , 1|0=1 , 0|1=1 , 0|0=0
    3. ^: 1^1=0 , 1^0=1 , 0^1=1 , 0^0=1
    4. ~: ~1=0 , ~0=1
  • 进制运算

    1. 二进制转为十六进制:小数点左边向左开始,右边向右开始,各取4位,不足的向左(向右)补零
      1. 二进制:010101 —— 十六进制:15
      2. 第一步:二进制分为:01,0101
      3. 第二步:补全:0001,0101
      4. 第三步:0001为1,0101为5(计算的时候要把顺序倒过来,0101看成1010计算)
  • 使用二进制表示负数

    1. 获得原码:00101111

    2. 获得反码:11010000

    3. 获得补码(反码加一):11010001

3.11 移位操作符

  • 左移操作符(<<):操作数向左移动,低位补零
  • 右移操作符(>>):操作数向右移动,当符号为正,高位补零;当符号为负,高位补1
  • 无符号右移操作符(>>>):无论正负,都在高位插入零

byte和short类型使用位移运算时,会先转换成int类

3.12 三元操作符

  • if-else操作符,形式为boolean-eep ? value1 : value2

    当结果为true时,就计算value1;当结果为false,就计算value2

  • 使用时需要注意可读性

3.13 字符串操作符+和+=

  • 需要考虑计算的优先级
package com.thirteen;

import static util.Print.*;

public class PrintString {
    public static void main(String[] args) {
        int x = 0 , y = 1 , z = 2;
        String s = "x,y,z";
        System.out.println(s+x+y+z);
        System.out.println(s+(x+y+z));
        System.out.println(x+y+z+s);
        System.out.println(x+""+s);
        System.out.println(""+x);
        System.out.println(x+y+z);
    }
}/* output
x,y,z012
x,y,z3
3x,y,z
0x,y,z
0
3
*/

3.15 类型转换操作符

  • 窄化转换:将能容纳更多信息的数据类型转化成无法容纳这么多信息的数据类型,存在风险
  • 扩展转换:新类型能够容纳更多信息,安全,不会造成任何信息的丢失

Java允许将任何基本数据类型转换成别的基本数据类型,但布尔类型不允许任何转换

“类”数据类型不允许类型转换,除非使用特殊方法

3.15.1 截尾和舍入

  • 截尾

    1. float和double转换成整型
  • 舍入

    1. 使用java.lang.Math中的round()方法

3.15.2 提升

表达式中的最大数据类型决定了表达式最终结果的数据类型

3.16 Java没有sizeof

所有数据类型在所有机器中的大小都是相同的

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容