第三章.操作符

来源:互联网 发布:淘宝宝贝设置价格区间 编辑:程序博客网 时间:2024/06/04 19:36

导语:

  • 在最底层,Java中的数据是通过使用操作符来操作的。

1.Java操作符的定义

  • 操作符接受一个或多个参数,并生成一个新的值,可能是boolean。+、-、*、/、和赋值号(=)的用法与其他编程语言相同。
  • 几乎所有的操作符都只能操作基本类型。
  • 例外的操作符是“=”、“==”、“!=”,这些操作符能操作所有的对象
  • String 类支持“+”和+=’。

2.优先级

  • 当一个表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序。
  • 顺序:先乘除后加减。
  • 可以有括号改变其优先级,括号内执行完,再执行操作符,括号明确规定了计算顺序。
    int x = 1, y = 2, z = 3;int a = x + y/2+z;int b = (x + y)/(2 + z);
  • 当编译器观察到一个String后面紧跟一个“+”,而这个“+”后面紧跟这一个非String类型的元素是,就会尝试着将这个非String类型的元素转换为String类型
  • “+”有时也做字符串连接符。

3.赋值

  • 赋值使用操作符“=”。意思是“取右边的值”,把它赋值给左边。
  • 右边可以是任何常数、变量或表达式,只要它生成一个同左边类型相同的值就行。
  • 但左值必须是一个明确的、已命名的变量。也就是说必须有一个物理空间可以存储等号右边的值。
    如 a = 4;
  • 常数不能作为左值
    如不能 : 4 = a;
    这是不合法的。
  • 基本类型赋值是简单的。基本类型存储的是实际的数值(它占用一定的物理空间),而并非指向一个对象的引用。
    所以在赋值的时候,是直接将内容从一个地方复制到了另一个地方,如a=b,b的内容赋给了a,但a改变b不会受到影响。
  • 在为对象赋值的时候,情况发生了变化。
    如果将“一个对象赋值给另一个对象”,实际上试将“引用”从一个地方复制到另一个地方。
    c=b,c若改变,改变的是对象,b和c指向同一个对象,b所持有的是a改变了的对象,反之亦然。
  • 一个对象若没有了引用,那么他迟早会被垃圾回收器回收。

4.算数操作符

  • java的算数操作符包括,+、-、*、/、以及取模操作符(%,他从整数除法中产生余数)。整数除法会直接去掉结果的小数位,而不是四舍五入。
  • 随机数产生(Random):
    1. 如果在创建过程中没有传递任何参数,那么Java就会将当前时间作为随机数生成器种子,并由此在程序每一次执行时都产生不同的输出。
    2. 通过在创建Random对象时提供种子,用于随机数生成器的初始化值,随机数生成器对于特定的种子值总是产生相同的随机数序列。
      就可以在每一次执行程序时产生相同的随机数。
  • 一元加、减操作符:只有一个参数参与。如 x = -a;编译器自动识别为 x = a*-1; 一元减号用于转变数据的符号。

5.自动递增和递减

  • 前缀式:表示“++”或“--”操作符位于变量或表达式的前面;会先计算,再生成值。
  • 后缀式:表示“++”或“--”操作符位于变量或表达式的后面;会先生成值,再计算。
    int i = 0;System.out.println(""+i++);//先输出i,再加1System.out.println(""+ ++i);//i先加1,再输出

6.关系操作符

  • 关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系。如果真,生成true,如果假,生成false
  • 关系操作符有小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、等于(==)以及不等于(!=)
  1. 关系操作符==和!=也适用于所有的对象。

7.== 和 equals()

  • ==号比较的是地址,即对象的存储空间、内存地址。
  • equals()比较的是对象的内容是否相同。
  • equals()默认比较的是引用,大多数java类库实现了equals()方法,以便用来比较对象的内容,而非比较对象的引用,但是我们自己写的类是默认的equals(),所以还是比较的引用。
    Integer i1 = new Integer(11);Integer i2 = new Integer(11);//java类库中的类,实现了equals()方法,比较内容,输出trueSystem.out.println(i1.equals(i2));Test t1 = new Test();Test t2 = new Test();//自己的类,没有实现equals()方法,比较的是引用,输出的是falseSystem.out.println(t1.equals(t2));

8.逻辑操作符

  • 逻辑操作符“与”(&&)、“或”(||)、“非”(!)能够根据参数的逻辑关系,生成一个布尔值(true或false)
  • “与”、“或”、"非"操作只能应用于布尔值。不可将一个非布尔值在逻辑表达式中应用,如 0||1 这样是错误的。
  • 逻辑操作符: 短路。即如果能够准确无误的确定整个表达式,就不在进行表达式余下的部分了。
    如 s = 1,int i = 2, s>0||i>0,这样后面的i>0就不会执行了,或,只要一个成立就行。
  • 所有的逻辑表达式都有一部分不必计算,那将获得潜在的性能提升。

9.直接常量

  • 直接常量后面的后辍字符标志了它的类型。如 float f = 3.0F,后面的F代表float型,当然F可以小写。
  • 十六进制适用于所有的整数数据类型,以前缀 0x或0X,后面跟随0-9或小写(或大写)的a-f来表示。
  • 如果将一个变量初始化成超出自身表示范围的值,编译器都会报错。
  • 八进制数由前缀0以及后续的0~7的数字来表示。

10.指数计数法

  • e代表自然对数的基数,约等于2.718。
  • 在java中看到像1.39e-43f ,它真正的含义是1.39*10(-43)。float f4 = 1e-43f;编译器通常会将指数作为双精度数来处理。所以如果后面没有f就会报错。

11.三元操作符

  • 三元操作符也称为条件操作符,他有三个操作数。
    表达式 boolean-exp ? value0 : value1,如果问号前面的boolean值时真(true),则返回value0否则 返回 value1
  • 三元操作符就是为了体现高效率编程的。

12.字符串操作符 + 和 +=

  • 字符串操作符 ,顾名思义,连接不同的字符串。
  • 如果表达式以一个字符串起头,那么后续所有操作数都必须是字符串类型。 编译器会把双引号内的字符序列自动转成字符串。

13.类型转换操作符

  • 在适当的时候,java会将一种数据类型自动转换成另一种。
  • 类型转换允许我们显示的进行这种类型的转换,或者在不能自动转换的时候强制进行类型转换。
  • 大转小【大的赋予小的】,需要进行强制类型转换(大转小会丢失数据),小转大,自动转换,不需要进行强制类型转换。
    float f = 1.1f;double d = 3.0f;d = f;f = (float) d;
  • 对象可以在其所属类型的类族之间可以相互进行类型转换。如“橡树”可以转型为“树”,反之亦然。但不能把它转型成类族以外的,如“岩石”。
    List<String> list ;ArrayList<String> arrayList = null;LinkedList<String> linkedList;list = arrayList;arrayList = (ArrayList<String>) list;


14.截尾和舍入

  • 如将float或double转型成整数是,总是对该数字执行结尾,即将小数点后的截去,也就是向后取整,而不是四舍五入。
    要想得到舍入的结果,使用Math中的round()方法。

15.提升

  • 表达式出现的最大的数据类型决定了表达式的最终结果的数据类型,
    如将一个float值与一个double值想成,结果就是double

16.java中没有sizeof

  • c 和c++中sizeof函数获取数据项分配的字节数。然而java不需要,因为 java中所有数据类型在所有机器中的大小是相同的。

17.按位操作符

了解按位操作符前请先了解 进制之间的转换http://blog.csdn.net/sinat_32955803/article/details/52155175

  • 按位操作符用来操作整数基本数据类型中的单个“比特(bit)”,即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
  • 按位操作符来源于C语言面向底层的操作,这种操作经常直接操纵硬件,设置硬件寄存器内的二进制位。
  1. 如果两个输入位都是1,则按位“与”操作符(&)生成一个输出位1;否则生成一个输出位0;
  2. 如果两个输入位只有一个是1,则按位“或”操作符(|)生成一个输出位1;只有在两个输入位都是0的情况下,它才会生成一个输出位0.
  3. 如果输入位的某一个是1,但不全都是1,那么按位“异或”(^)生成一个输出位1.
  4. 按位“非”(~),取反操作符,它属于一元操作符(也就是一个数操作),只对一个操作数操作。按位“非”生成与输入相反的值——若输入0,则输出1,;若输入1,则输出0。
  • 按位操作符可与等号(=)联合使用,以便合并运算和赋值,&=、|=、^=都是合法的,但由于“~”是一元操作符,所以不能与=联用。
  • 可以将boolean值作为一种但比特对待,可以对它执行按位“与”、“或”、和按位“异或”运算,但不能执行按位“非”(大概是为了避免与逻辑NOT(!)混淆)
  • 对于boolean值,按位操作符具有与逻辑操作符相同的效果,只是它们不会中途“短路”,也就是说会一直判断下去。
  • 具体操作请看http://www.cnblogs.com/dongpo888/archive/2011/07/13/2105001.html

18.移位操作符

  • 移位操作符操作的运算对象也是二进制的“位”。移位操作符只可用来处理整数类型。
  1. 左移位操作符(<<)能够按照操作符右侧指定的位数将操作符左边的操作数向左移动(最高位移出,在低位补0)。
    当左移的运算数是int 类型时,每移动1位它的第31位就要被移出并且丢弃;
    当左移的运算数是long 类型时,每移动1位它的第63位就要被移出并且丢弃。
    当左移的运算数是byte 和short类型时,将自动把这些类型扩大为 int 型。
    数学意义
    在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方
    eg:3 <<2(3为int型)下面所有都是以int为例
    1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011,
    2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,
    3)在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 00001100,
    转换为十进制是12。
    当移动的位数超过该类型的最大位数时:这种情况比较特殊
    当移出的位数/32余数为0时,移位的数字又会还原回来,归零,重新进行移位,
    比如3移位32位(3>>32),还是3,移位64位还是3,当移位65位(3>>33)或33位时,又会按照以前的规则移位了,移动33位就相当于左移了一位
    负数的移位和正数的移位相同,高位移出,低位补0.
    如:-2<<2
    11111111111111111111111111111110
    11111111111111111111111111111000 -8

    当移动的位数是负数时如 1<<-1;有一个简单的方法就是32+-1 = 31,所以移动-1位就和移动31位是一样的,当移动的负数超过32时如-33,其实就和上面正数超过32位一样,一切又还原啦,
    移动33位相当于移动-1位,相当于移动了32+-1=31位:
    原理:i<<-1和i<<31 的结果一样
    1 “-1”表示成补码是1111 ....11 1111 ,31是 0000  ...0011 1111,,他们的后六位是一样的。
    2 Interger的移位运算只注意后6位,看注释
         Note also that rotation by any multiple of 32 is a no-op, so all but the last five bits of the rotation distance can be ignored, even if the distance is negative:
    总结:将负数写为补码,这个数的低6位便是其真正移位的数字。

  1. “有符号”右移位操作符(>>)则按照操作符右侧指定的位数将操作符左边的操作数向右移动。
    “有符号”右移位操作符使用“符号扩展”:若符号为正,则在高位插入0,若符号为负,则在高位插入1.,以下均已int型为例
    运算规则:按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1.
    例如5>>2=1,则是将数字5右移2位
      计算过程:5的二进制形式为:0000 0000 0000 0000 0000 0000 0000 0101,然后把低位的最后两个数字移出,因为该数字是正数,所以在
        高位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 0001.转换为十进制是1.
        数学意义:右移一位相当于除2,右移n位相当于除以2的n次方(不能整除的用取整)。
        例如-5>>2=-2 则是将数字-5右移2位   
        计算过程:

       -5的二进制形式:1000 0000 0000 0000 0000 0000 0000 0101

             转换成补码:1111 1111 1111 1111 1111 1111 1111 1011

           移位高位补1:1111 1111 1111 1111 1111 1111 1111 1110

          再转换成原码:1000 0000 0000 0000 0000 0000 0000 0010

           得到结果-2

    移出的位数超过类型的最大位数和右移位数为负数【3>>-2】的情况。和左移操作符相同,超出则还原。

  2. java中增加了一种“无符号”右移位操作符(>>>),它使用“零扩展”,无论正负,都在高位插入0。特殊情况和上面两种相同
  • 如果对char、byte、或者short类型的数值进行移位处理,那么在移位进行之前,他们会被转成int类型,并且得到的结果也是一个int类型的值。
    只有数值右端的低5位才有用,这样可以防止移位超过int型值所具有的位数,【2的5次方是32,int只有32位】
    一个long类型的数值进行处理,最后得到的结果也是long。此时只会用到右端的低6位防止long类型具有的位数
  • “移位”可与“等号”(<<=  >>=或>>>=)组合使用。此时操作符左边的值会移动有右边的值指定的位数,再将得到的结果附给左边的变量。
    在进行“无符号”右移位结合赋值操作时,可能会遇到一个问题,如果对byte或short值进行这样的移位运算,得到的可能不是正确的结果。
  • 他们会先转换成int类型,再进行右移操作,然后被截断,赋值给原来的类型,在这种情况下可能得到-1的结果。




0 0