美文网首页Java基础
Java编程思想笔记3.操作符

Java编程思想笔记3.操作符

作者: 卢卡斯哔哔哔 | 来源:发表于2018-11-09 10:38 被阅读2次

    点击进入我的博客

    3.1更简单的打印语句

    System.out.println("imbug");
    

    通过编写一个小类库,并通过import static该方法来实现简化打印(基本没啥用)。

    public class Print {
        public static void println(String str) {
            System.out.println(str);
        }
    }
    
    import static s1.Print.println;
    
    public class Test {
        public static void main(String[] args) {
            println("imbug");
        }
    }
    

    3.2 使用Java操作符

    • 操作符接受一个或多个参数,并生成一个新值
    • 有些操作符可能会改变操作数本身的值
    • 几乎所有的操作符都只能操作基本类型===!=能操作所有的对象;String类支持++=操作符

    3.3 优先级

    运算符优先级表.png
    • 操作符是有优先级的。
    • 个人认为:死记硬背操作符的优先级除了应付大学考试和智障笔试题之外,并无卵用~只要理解了运算符的原理再来看优先级有易如反掌了~
    • 如果有人写这样的代码请打死他System.out.println(a<<=b+=c>>=5);
    • System.out.println()中的+运算符可能会表示字符串拼接,还有可能进行字符串转换。

    3.4 赋值

    赋值=的意思是取右边的值把它复制给左边。
    左边的值必须是明确的、已命名的变量。
    右值可以是任何常熟、变量或者表达式(只要它能生成一个值)。
    基本类型传递的是值,对象类型传递的是引用。

    3.5 算术操作符

    +-*/%
    /:整数的除法会直接干掉小数位而不是四舍五入
    +-:还可以用作正负号

    3.6 自动递增和递减

    ++--
    前缀式:++a先执行运算再生成值,即++a == a is true
    后缀式:a++先生成值再执行运算,即a == a++ is true

    3.7 关系运算符

    ><>=<=!===

    • 关系操作符生成的是一个boolean的结果。
    • 大于小于大于等于小于等于不适用于boolean类型
    • 等于不等于适应于全部基本数据类型对象类型
    • 等于不等于作用于对象类型时比较的是引用(我更倾向于用C++中的地址来理解这个概念)
    • 对基本数据类型的包装类、StringBigIntegerBigDecimalequals方法比较的是值
    • 如果你自己的class没有重写equals方法,那么equals方法使用的是Objectequals方法,即比较引用。

    数值的包装类

        Integer x1 = new Integer(10);
        Integer x2 = new Integer(10);
        System.out.println("x1 == x2: " + (x1 == x2));
        System.out.println("x1.equals(x2): " + x1.equals(x2));
        // x1 == x2: false
        // x1.equals(x2): true
        Integer y1 = 10;
        Integer y2 = 10;
        System.out.println("y1 == y2: " + (y1 == y2));
        System.out.println("y1.equals(y2): " + y1.equals(y2));
        // y1 == y2: true
        // y1.equals(y2): true
        Integer z1 = 1000;
        Integer z2 = 1000;
        System.out.println("z1 == z2: " + (z1 == z2));
        System.out.println("z1.equals(z2): " + z1.equals(z2));
        //z1 == z2: false
        //z1.equals(z2): true
    

    上述代码的.class文件反编译后的代码

        Integer x1 = new Integer(10);
        Integer x2 = new Integer(10);
        System.out.println((new StringBuilder()).append("x1 == x2: ").append(x1 == x2).toString());
        System.out.println((new StringBuilder()).append("x1.equals(x2): ").append(x1.equals(x2)).toString());
        Integer y1 = Integer.valueOf(10);
        Integer y2 = Integer.valueOf(10);
        System.out.println((new StringBuilder()).append("y1 == y2: ").append(y1 == y2).toString());
        System.out.println((new StringBuilder()).append("y1.equals(y2): ").append(y1.equals(y2)).toString());
        Integer z1 = Integer.valueOf(1000);
        Integer z2 = Integer.valueOf(1000);
        System.out.println((new StringBuilder()).append("z1 == z2: ").append(z1 == z2).toString());
        System.out.println((new StringBuilder()).append("z1.equals(z2): ").append(z1.equals(z2)).toString());
    
    通过new Integer新建对象
    • new Integer每次都会新建对象,所以==的结果为false
    自动装箱与拆箱
    • 自动装箱:用赋值运算符=把一个数值或基本类型变量赋值给一个包装类变量(Integer y1 = 10)。装箱调用的是Integer.valueOf(10)方法。
    • 自动拆箱:用赋值运算符=把一个包装类赋值给一个基本类型变量(int y3 = y1),或者是在包装类进行数值运算时。拆箱调用的是Integer#intValue()方法。
    • 装箱方法的坑(笔面试题):下面是Integer.valueOf(int i)的源代码。可以看出当装箱的数值在-128到127之间是,返回的对象是IntegerCache中提前new出来的对象,所以y1 == y2的结果是true;当装箱的数值超出该范围,则返回的是new出来的对象,所以z1 == z2的结果为false
    • 其他的装箱方法:ByteShortIntegerLong的范围都是[-128,127];Character的范围是[0,127];FloatDouble全部是new出来的新对象;Boolean都是预定义好的truefalse。有趣的是,这些代码作者是一样的,但写法各不相同。
        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    

    备注内容:可以从https://varaneckas.com/jad/下载Java反编译工具JAD;或者可用从http://jd.benow.ca/下载反编译工具JD-GUI

    3.8 逻辑操作符

    &&||!

    • 逻辑运算符只能根据两个布尔值参数的逻辑关系,生成一个布尔值。
    布尔值短路
    • 即一旦能够明确无误地确定整个表达式的值,就不再计算表达式剩余的部分了
    • &&:遇到第一个false则不执行后边的代码
    • ||:遇到第一个true则不执行后边的代码
        public static boolean func1() {
            System.out.println("func1");
            return true;
        }
    
        public static boolean func2() {
            System.out.println("func2");
            return false;
        }
    
        public static boolean func3() {
            System.out.println("func3");
            return true;
        }
        if(func1() && func2() && func3());  // 不执行func3中的内容
        if(func1() || func2() || func3());  // 不执行func2和fanc3中的内容
    
    • 面试题:如何不使用条件语句控制流程。
        // 不使用if来控制该流程
        if(func1()) {
            func2();
        }
        // 方法
        boolean var = func1() && func2();
    

    3.9 直接常量

    • 前缀0x0X:表示16进制数字
    • 前缀0:表示8进制数字
    • 后缀lL:表示long类型。在写代码的时候,由于小写的l容易和数字1混淆,所以各种规范中都不建议(禁止)使用小写的l表示长整数。最简单就全部用大写就好了!
    • 后缀fF:表示float类型。
    • 后缀dD:表示double类型。
    • eE:指数计数,表示10的幂

    3.10 按位操作符

    &|^
    &=|=^=

    • boolean:可以把boolean值看成单比特值对待,&|^的操作相同,但是不能用于布尔值

    3.11 移位操作符

    <<:高位(包括符号位)舍弃,低位补零。
    >>:有符号右移运算,若高位是1,则高位补1;若高位是0,则高位补0。
    >>>:无符号右移,最高位补0。

    • 移位操作符只能用来处理整数类型。
    • charbyteshort进行移位操作时,会先被转成int类型,并且结果也是int类型
    • long类型移位还是long

    <<=>>=>>>=

    • 注意:在对byteshort进行>>>=无符号右移等于运算时,整个流程是先向上转化成int——进行移位运算——向下转化(强制截取)成byteshort,所以会导致移位后对结果不正确。
        short s = -1;
        System.out.println(Integer.toBinaryString(s));
        // 11111111111111111111111111111111
        System.out.println(Integer.toBinaryString(s >>> 10));
        // 1111111111111111111111
        s >>>= 10;
        System.out.println(Integer.toBinaryString(s));
        // 11111111111111111111111111111111
    

    3.12 三目运算符

    boolean-exp ? val1 : val2

    3.13 字符串运算符

    ++=

    3.14 操作符常犯错误

    • Java中ifwhile语句必须使用boolean值,所以不会出现==被写成=的问题;除非是两个boolean
    • Java编译器也能够防止逻辑与或(&&||)和按位与或(&|)的问题,除非是两个boolean

    3.15 类型转换操作符

    • 既可以对数值进行转换,也可以对数值变量进行转化
    • 向下转化必须要强制转化,否则编译失败(移位等于、算数等于时不会)
    • 向上转化不必显示进行转化
    • 布尔值之外,其他类型都可以互相转化
    • 浮点数转成整数值的时候直接截尾,不会进行四舍五入
    • 表达式的最大数据类型决定了表达式的数据类型

    3.16 没有sizeof

    Java所有基本数据类型的size是确定的,所以不需要sizeof

    3.17 操作符小结

    • charbyteshort在使用算术操作符和移位操作符的时候都会被转成int,必须显示类型转换回原来的类型。以下注释掉的都是编译错误的。
            short s1 = 10;
            short s2 = 10;
            // short s3 = s1 + s2;
            // short s4 = s1 >> 1;
    
    • charbyteshort在进行复合赋值运算(移位等于、算数等于)时不需要强制转化。
    • int类型要小心结果溢出
    • boolean外,任何基本类型都可以通过类型转换变成其他基本类型
    • 必须留意向下转化的的结果,因为可能存在丢失信息的可能性

    相关文章

      网友评论

        本文标题:Java编程思想笔记3.操作符

        本文链接:https://www.haomeiwen.com/subject/evpkxqtx.html