我的Thinking in Java学习笔记(四)

原创 2004年08月18日 17:32:00

   逻辑运算符
     逻辑运算符 AND(&&)?? OR(||)? NOT(!)? 都会得到一个boolean值,且他们只能用于boolean身上。逻辑表达式中的boolean无法使用类似于c/c++中的数值代替。注意,boolean被用于一个预期会出现string的地方,其值会自动转换为适当的文本形式,并且假如2个比较的基本数据类型不相同,也是可以比较的~例如10和10.0d,结果也是会返回true的
     短路式的核定
     这个的意思就是逻辑表达式中的部分语句可能因为逻辑运算符的使用不当,导致有些语句并没有经过判断,只要大家细心点,掌握知识牢靠就没什么问题~
    
位运算符
    位运算符可以让你操作整数基本数据类型中的个别bit位,切记是整数基本数据类型!位运算符直接造作的是数据中的0和1,直接面向硬件,所以有的人说java无法控制底层硬件,这个说法是不正确的,你完全可以直接控制硬件~好象asm一样~
    位运算符
    AND(&)会在2个输入位全为1时,产生一个输出位1,否则为0;
    OR(|)会在2个输入位有任意一个为1时,产生一个输出位1,当2个输入位全部为0时,输出0;
    XOR(^)会在2个输入位上有且只有一个输入位为1时,产生输出位1;
    NOT(~)也叫做"一的补数运算符",是一个一元运算符(其他的是2元预算符),他仅仅接受一个引数,并且产生相反位
    注意,位运算符和逻辑运算符很想。但是他们是有区别的,我曾经见过一个招聘题目,其中就有让你阐述他们的区别,除了’~‘之外,任何一个位运算符都可以和赋值运算符=号合用,类似于+=
    boolean,你可以在他身上执行除了not之外的任何一个位运算符;对于boolean而言,位运算符和逻辑运算符的唯一区别就是位运算符不做短路式,最后boolean是无法做位移运算的
   位移运算符
     位移运算符也是用来操作位的,也是只能作用在整数基本数据类型上在java中采用补码表示二进制数,在补码表示中,最高为为符号位,正数符号位是0,负数符号位是1,补码的规定如下:
      对于正数来说,最高位是0,其余各位代表数值本身的二进制数;
      对于负数来说,把该数的绝对值的补码按位取反,然后对整个数+1,取得该数的补码。如-1的补码为11111111,-1的绝对值补码是00000001,按位取反11111110,再加1,11111111
      左移运算符(<<)会左操作数向左迁移,迁移的位数由右操作数决定(左移后,低位补0)a=a<<2,使a的各个二进制位左移2位,右补0,若a=00001111则a<<2=00111100,高位左移后溢出的位舍弃掉了在不产生溢出的情况下,左移一位相当于乘2,用这种方法来实现乘法,要比乘法运算快很多,所以有的公司在效率题目上,会出这样的题。
     右移运算符(>>)会使左操作数向左迁移,迁移的位数由右操作数决定,面对带有正伏负号的迁移,右移运算符先会采用一种叫符号扩展的措施:如果原值为正数,高位补0;如果原值为负数,则高位补1。
     此外,java中还增加了无正负号的右移运算符(>>>)采用的是零扩展措施:无论原值是正还是负。一律在高位补0,如果你操作的位移对象是char 、byte、short 的话,在位移进行的时候,会把他们先提升为int,才进行位移,当然结果也是int的。位移运算中位移的位数,对于int类型的数据来说,只有低位的5个bit位是有用的,对于long来说,只是低位的6个bit位是有用的。
     位移运算符和其他运算符一样,也是可以和=号并用的,但是当在byte和short上进行无正负号的>>>=时候就有问题了,因为他们会先被提升为int,然后右移,再赋值回来,但是当他们赋值回来的时候,超过他们的容量大小的高位会被截去,就会产生很奇怪的数字-1
     public class test
     {
     public static void main(String args[])
     {
      int i=-1;
      long l=-1;
      short s=-1;
      byte b=-1;
      i>>>=10;
      System.out.println(i);//1
      l>>>=10;
      System.out.println(l);//2
      s>>>=10;
      System.out.println(s);//3
      b>>>=10;
      System.out.println(b);//4
      b=-1;
      System.out.println(b>>>10);//4
      }
     }

     答案是?4194303、18014398509481983、-1、-1
     4194303需要注意的是这个答案,因为第4个移位后的结果并没有传回b,所以才能显示正确的答案,这个答案之所以和第一个是一样的,因为b被提升成int b了,所以答案和int i的是一样的!
    if-else 三元运算符
     这个好象是java中唯一的一个3元运算符,呵呵~他的格式是
     boolean-exp?value1: value2
     如果boolean-exp的判断是true 则执行value1,如果为false,则执行value2,这个和if-else语句是一样的~但是他要比
     if-else语句要精练,并且执行的效率要比他高!
     需要注意的是:value2中的语句是要带有;号的,并且不能放进去System,out.println();之类的语句的,我们是用3元运算符要的是他的运算结果值,并不是if-else所能实现的控制程序流程。
    逗号运算符
    在java中,唯一能放;号运算符的地方,就是for循环中,这个我们会在以后讲到应用于string身上的operator+这个问题我在我的"java初学者容易出现的运算符问题"中已经提到了~在java中,假如+号在string之前出现,执行的是运算,而要是在string 后出现,则执行的是字符连接,例如
     
public class test
     {
      public static void main(String args[])
      {
       int x=1,y=2,z=3;
       String s="string";
       System.out.println(x+y+z+s);
       System.out.println(s+x+y+z);
       System.out.println(x+y+s+z);
      }
     }
 显示6string
 string123
 3string3??
    转型运算符
     转型分为2类,自动转换和强制转换,自动转换就是系统自动进行的宽化转换,例如byte类型的b +1时,系统会自动把他的byte类型转化为int类型,你可以使用byte b=b+1;看看就知道了,系统就会告诉你possible loss of precision,因为你在加1的时候,b的值已经是int类型了,你也没办法再赋值回b了,系统在比int小的数据类型上进行运算时会把他们的值提升为int,而在和long运算时会提升为long,以此类推。所谓的强制转换,就是你告诉编译器,我知道b是个int类型但是他的表达值并没有超过byte的范围,你就放心的转化吧~也就是这么一句话:b=(byte)(b+1);他就会把int缩小为byte,但是假如你运算完的值大于了原来类型表达范围,但是你还要强制转换,发生了内存溢出,那么溢出的bit位会被抛弃,发生数据丢失现象。java中只允许除了boolean之外的基本数据类型的类型转换,这个要记牢
     
字面常量
      一般而言,当你将某个常量放到程序中,编译器很清楚的知道要将他制成什么类型,但是有的时候为了避免模糊不清,我们就可以为常量搭配一些特殊的字符,来引导编译器的正常判断,在常量值后添加l/L指的是long类型,添加f/F指的是float类型,d/D指的是double类型。而十六进制的表达方法是以0x/0X开头,八进制是以0开头,但是java中不提供二进制的表达方法,你需要注意这几个类型所能表达的十六进制最大值
    
char 0xffff????? byte 0x7f??????? short? 0x7fff?? int? 0x7fffffff
    
java没有sizeof运算符
    再谈优先级
     还是那句话,不清楚的时候加括号~嘿嘿~也不用记那些烦琐的优先级了~
     最后一点:当2个最够大的int相乘时所发生的溢出而导致的异常,java是不会在编译期或者是运行期报告的~这个应该算是他的一个小bug了~


我的下一篇文章会讲到流程控制,欢迎关注,有什么问题,可以这样联系我
E-mail
molmd@163.net /163.com QQ:31349283 我们可以共同学习进步!
欢迎访问我的blog,
http://blog.csdn.com/maoerzuozuo 里面有更多学习内容!
 

读第一遍Thinking in java的笔记

第一章1.Java一切都是对象,但操纵的标识符是对象的一个“引用”。简单的说,引用代表这个对象内存地址。 如:String s;实际上,我们并没有创建一个对象,我们只是创建了一个引用,它不指向任何...
  • u011253016
  • u011253016
  • 2016年07月18日 18:22
  • 1457

我的openwrt学习笔记(一):OpenWrt简介

我的openwrt学习笔记(一):OpenWrt简介     关于 OpenWrt openwrt是嵌入式设备上运行的linux系统。OpenWrt 的文件系统是可写的,开发者无需在每一次修改...
  • xushx_bigbear
  • xushx_bigbear
  • 2015年08月18日 08:45
  • 3810

Thinking In Java 学习笔记(一)

最近都在学习java,以下是学习笔记。 1 线程 1.1基本线程处理 1)throw与throws的区别 前者用于抛出单个异常,并且该异常知道如何处理,通常是放在catch子句块中,当...
  • buleideli
  • buleideli
  • 2013年01月12日 11:04
  • 1289

Thinking In Java 学习笔记(四)

接本系列上篇。 2.8 容器 1)容器不能保存基本数据类型 但是可以保存integer这种封装基本数据类型的类。 小贴士 Arrays.fill static void...
  • buleideli
  • buleideli
  • 2013年03月11日 13:39
  • 936

Thinking In java学习笔记

  • 2014年10月05日 21:24
  • 324KB
  • 下载

Thinking in java学习笔记

  • 2012年03月23日 15:58
  • 428KB
  • 下载

thinking in java 学习笔记(三)之重载

简单通过书中的例子,重新温习了一下重载: package com.halberd.extend; class Tree { int height; Tree() { System.o...
  • wclxyn
  • wclxyn
  • 2012年04月01日 23:51
  • 1118

(Thinking in Java学习笔记)字符串(用Markdowm写的)

不可变StringString对象是不可变的。 String类中每个看起来会修改String值得方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。 而最初的String对...
  • JedreckZhou
  • JedreckZhou
  • 2016年11月03日 21:08
  • 157

Thinking in Java学习笔记 Semaphore控制的资源池

SemaphoreDemo.java 一个资源池Pool,可以由多个线程检出和检入其中的资源,由Semaphore控制同步问题,由数组来记录每个资源的检出/检入状态 CheckoutT...
  • fantasyagain
  • fantasyagain
  • 2015年02月27日 14:04
  • 763

Thinking In Java 学习笔记(三)

接本系列上篇。 1 基础复习摘要 2.1 Finalize()使用 该函数只在垃圾回收器就要释放空间时,才会调用的。因此不能等同于C++的析构函数。 Finalize中进行的清除工作,主要是对...
  • buleideli
  • buleideli
  • 2013年03月11日 13:36
  • 777
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:我的Thinking in Java学习笔记(四)
举报原因:
原因补充:

(最多只允许输入30个字)