资讯专栏INFORMATION COLUMN

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

wpw / 1816人阅读

摘要:自动拆箱用赋值运算符把一个包装类赋值给一个基本类型变量,或者是在包装类进行数值运算时。指数计数,表示的幂按位操作符可以把值看成单比特值对待,的操作相同,但是不能用于布尔值。移位操作符高位包括符号位舍弃,低位补零。

点击进入我的博客 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 优先级

操作符是有优先级的。

个人认为:死记硬背操作符的优先级除了应付大学考试和智障笔试题之外,并无卵用~只要理解了运算符的原理再来看优先级有易如反掌了~

如果有人写这样的代码请打死他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/下...;或者可用从http://jd.benow.ca/下载反编译...
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外,任何基本类型都可以通过类型转换变成其他基本类型

必须留意向下转化的的结果,因为可能存在丢失信息的可能性

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72151.html

相关文章

  • Java编程思想笔记4.控制执行流程

    摘要:在初始化和步进控制部分,可以用一系列由逗号分割的语句,而且那些语句会独立执行。和都表示无限循环语法数组等关键词有两个方面的用途一方面指定一个方法返回什么值另一个方面指定当前的方法退出,并返回那个值。 点击进入我的博客 4.1 true&false Java的条件语句只能使用布尔值来决定执行路径 4.2 if-else 4.3 循环语句 while、for、do-while do-...

    PingCAP 评论0 收藏0
  • Java编程思想笔记13.字符串

    摘要:的构造器经过重载可以接受多种输出目的地,不过最常用的还是和。组号为表示整个表达式,组号表示被第一对括号括起的组,依此类推。有多个重载的构造器,可以接受和对象。 点击进入我的博客 字符串操作是计算机程序设计中最常见的行为 13.1 不可变String String底层是由char[]实现的,是不可变的。看起来会改变String的方法,实际上都是创建了一个新的String对象,任何指向它...

    since1986 评论0 收藏0
  • Java编程思想笔记11.持有对象

    摘要:迭代器通常被成为轻量级对象创建它的代价很小。与迭代器可以用于数组和所有对象,之所以能够工作,是因为继承了接口。 点击进入我的博客 我觉得本章名字改成容器似乎更好理解,持有对象让人感到一头雾水我们需要在任意时刻和任意位置创建任意数量的对象,所以依靠创建命名的引用来持有对象已经满足不了需求。Java可以用数组和其他容器类来(List、Set、Queue、Map)来解决这个问题,不同的容器...

    newtrek 评论0 收藏0
  • Java编程思想笔记01------一切都是对象

    摘要:一引用操纵对象在的世界里,一切都被视为对象。特点创建程序时,需要知道存储在栈内所有数据的确切生命周期,以便上下移动堆栈指针。因为,指向同一块内存空间除了通过对象引用静态变量,我们还可以通过类直接引用静态变量 一、引用操纵对象 在Java的世界里,一切都被视为对象。操纵的标识符实际上是对象的引用, 例如:遥控器与电视的关系。 可以在没有对象关联的情况下,拥有一个引用。没有电视机,也可以拥...

    yuanxin 评论0 收藏0
  • Java编程思想笔记2.一切都是对象

    摘要:方法的基本组成包括名称参数返回值方法体方法名和参数列表唯一的标识出某个方法。如果返回的类型是,则的作用仅是退出方法否则必须返回正确的返回值包名名字可见性约定以域名反转作为包名,用来划分子目录,并且全部小写。 点击进入我的博客 2.1用引用操纵对象 尽管一切都看作对象,但操纵的标识符实际上是对象的一个引用。 String s; // s是一个String类型的引用, 并没有任何对象与其...

    taohonghui 评论0 收藏0

发表评论

0条评论

wpw

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<