Java虚拟机工作原理JVM_第1页
Java虚拟机工作原理JVM_第2页
Java虚拟机工作原理JVM_第3页
Java虚拟机工作原理JVM_第4页
Java虚拟机工作原理JVM_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、AstheJavaVirtualMachineisastack-basedmachine,almostallofitsinstructionsinvolvetheoperandstackinsomeway.Mostinstructionspushvalues,popvalues,orbothastheyperformtheirfunctions.Java虚拟机是基于栈的(stack-basedmachine)。几乎所有的java虚拟机的指令,都与操作数栈(operandstack)有关.绝大多数指令都会在执行自己功能的时候进行入栈、出栈操作。1Java体系结构介绍Javasiarchitect

2、urearisesoutoffourdistinctbutinterrelatedtechnologies,eachofwhichisdefinedbyaseparatespecificationfromSunMicrosystems:1.1 Java体系结构包括哪几部分?Java体系结本包括4个独立但相关的技术theJavaprogramminglanguage程序设计语言theJavaclassfileformat字节码文件格式theJavaApplicationProgrammingInterface应用编程接口theJavaVirtualMachine虚拟机1.2 什么是JVMjava

3、虚拟机和javaAPI组成了java运行时。1.3 JVM的主要任务。Java虚拟机的主要任务是装载class文件并执行其中的字节码。Java虚拟机包含了一个类装载器。类装载器的体系结构二种类装载器启动类装载器用户定义的类装载器启动类装载器是JVM实现的一部分当被装载的类引用另外一个类时,JVM就是使用装载第一个类的类装载器装载被引用的类。1.4 为什么java容易被反编译?因为java程序是动态连接的。从一个类到另一个类的引用是符号化的。在静态连接的可执行程序中。类之间的引用只是直接的指针或者偏移量。相反在java的class文件中,指向另一个类的引用通过字符串清楚的标明了所指向的这个类的名

4、字。如果引用是指向一个字段的话。这个字段的名字和描述符(字段的类型)会被详细说明。如果引用指向一个成员方法,那么这个成员方法的名字和描述符(方法的返回值类型,方法参数的数量和类型)会被详细说明。包含对自己字段和成员方法的符号引用。包含可选的调试信息。(包括局部变量的名称和类型)1.5 垃圾回收器缺点:无法确认什么时候开始回收垃圾,无法确认是否已经开始收集,也无法确认要持续多长时间2平台无关3安全4网络移动性5Java虚拟机nativemethodlibrariesruntimedataarcticexecution一,碇加山.engineJ1加)thread1thread2thread3pcr

5、egistersJavastacksLinkVerifyPrepare(oplionally)ResolveInitialize每个JVM都有一个类装载子系统。运行时数据区:方法区,堆,java栈,pc寄存器,本地方法栈每个JVM实例都有一个方法区和堆。M们是由该虚拟机中所有线程共享的。每个线程都会得到自己的pc寄存器和java-,pc寄存器的值指示下一条将被执行的指令。java栈记录存储该线程中java方法调用的状态。(包括局部变量,参数,返回值,运算的中间结果。)这些内存区域是私有的。任何线程都不能访问另一个线程的pc寄存器和java栈java栈由许多栈帧组成。一个栈帧包含一个java方法

6、的调用的状态。当线程调用一个方法的时候,虚拟机压入一个新的栈桢到该线程的java栈中。当方法返回时,这个栈桢被从java栈中弹出并抛弃。引用有3中,类类型,接口类型,数组类型。JVM中,最基本的数据单元是字。上少选择32位作为字长。JVM有两种类装载器:启动类装载器(JVM实现的一部分,每个JVM都必须有一用户自定义的类装载器(JAVA程序的一部分,必须继承java.lang.CloassLoade|)。由不同的类装载器装载的类被放在虚拟机内部的不同的命名空间中。方法区:大小不固定,根据需要动态调整方法区可以被垃圾回收包含提取装载的类的信息,放到方法区JVM总能通过存储于方法区的内存信息来确定

7、一个对象需要多少内存类的静态变量也放到方法区。虚拟机为装载的每个类存储如下信息:这个类型的全限定名这个类型的直接超类的全限定名这个类型是类类型还是接口类型这个类的访问权限修饰符任何直接超接口的全限定名的有序列表该类型的常量池该类型所用常量的一个有序集合,包括直接常量(String,Integer,floatingpoint),和对其他类型,字段,方法的符号引用字段信息字段名字段类型字段的修饰符声明的顺序方法信息方法名方法的返回值类型方法的参数和类型,顺序方法的修饰符方法的操作码操作数栈和该方法的栈帧中局部变量区的大小异常表除了常量以外的所有类(静态)变量一个到类CloassLoader的引用一

8、个到Class类的引用方法表虚拟机为每一个装载的非抽象类都生成一个方法表一个java程序独占一个JVM,一个JVM中只存在一个堆。|所以,每个java程序有它自己的堆,但同一个java程序的1个线程共享一个堆运行时创建的所有类实例数组对象垃圾回收器回收内存移动对象以减少碎片不必是连续的内存,可以动态的扩展和收缩一个JVM的实现的方法区可以在堆顶实现栈帧栈帧由3部分组成:局部变量区,操作数栈,帧数据区。局部变量区,操作数栈的大小在编译的时候就确定了。局部变量区以字长为单位,从。开始计数的数组。int,float,reference,returnaddress只占据一个字长byte,short,c

9、har存入数组前转换成int,占据一个字长long,double占据2个字长。包含对应方法的参数和局部变量,方法的局部变量任意决定顺序,甚至一个索引指代两个变量,(当2个变量的作用域不重复时)操作数栈以字长为单位的数组,但不是通过索引来访问,而是通过标准的栈操作存贮数据的方式和局部变量区一样。帧数据区帧数据区保存常量池解析,正常方法返回,异常派发机制等信息执行引擎线程:JVM只规定了最高级别的线程会得到大多数的CPU时间,较低优先级别的线程,只有在所有比它优先级更高的线程全部阻塞的情况下才能保证得到CPU时间。级别低的线程在级别高的线程没有被阻塞的时候,也可能得到CPU时间,但是这没有任何保证

10、。每个虚拟机都有一个主存,用于保存所有的程序变量(对象的实例变量,数组的元素,以及类变量)。每一个线程都有一个工作内存,线程用它保存所使用和赋值的“工作拷贝”。局部变量和参数,因为他们是每个线程私有的,可以逻辑上看成是工作内存或者主存的一部分。6字节码文件8位字节的二进制流classFile表的格式Type	NameCountu4magic1u2minor_version1u2major_version1u2constant_pool_count1cp_infoconstant_poolconstant_pool_count-1u2access_flags1u2this_clas

11、s1u2super_class1u2interfaces_count1u2interfacesinterfaces_countu2fields_count1field_infofieldsfields_countu2methodscount1method_infomethodsmethods_countu2attributes_count1attribute_infoattributesattributes_countConstantpooltags常量池标志每一个标志都有一个相对应的表。表名通过在标志后面加上"info"后缀来产生EntryTypeTagValueDesc

12、riptionCONSTANT_Utf81AUTF-8encodedUnicodestringCONSTANT_Integer3AnintliteralvalueCONSTANT_Float4AfloatliteralvalueCONSTANT_Long5AlongliteralvalueCONSTANT_Double6AdoubleliteralvalueCONSTANT_Class7AsymbolicreferencetoaclassorinterfaceCONSTANT_String8AStringliteralvalueCONSTANT_Fieldref9Asymbolicrefere

13、ncetoafieldCONSTANT_Methodref10AsymbolicreferencetoamethoddeclaredinaclassCONSTANT_InterfaceMethodref11AsymbolicreferencetoamethoddeclaredinaninterfaceCONSTANT_NameAndType12Partofasymbolicreferencetoafieldormethod7类型的声明周期装载通过该类型的完全限定名,产生一个该类型的二进制数据流解析这个二进制数据流为方法区内的内部数据结构(并在堆上)创建一个表示该类型的java.lang.Cla

14、ss类的实例连接(已读入的二进制形式的类型数据合并到虚拟机的运行时状态中去)验证(保证java类型数据格式正确并适合JVM使用)准备(分配内存,默认初始化在此时发生)解析(把常量池中的符号引用(类,接口,字段,方法)转换为直接引用,虚拟机的实现可以推迟解析这一步,它可以在当运行中的程序真正使用某个符号引用是再去解析它)初始化(将类变量赋予适当的初始值(显式初始化),所有JVM的实现必须在每个类或接口首次主动使用是被初始化)对象的生命周期类实例化有四种途径:new调用Class或者java.lang.reflect.Constructor的newInstance()clone()java.io.

15、ObjectInputStream的getObject()8连接模型动态连接和解析常量池:class文件把它所有的引用符号保存在一个地方,常量池每个文件有一个常量池每一个被JVM装载的类或者接口都有一份内部版本的常量池,被称作运行时常量池运行时常量池映射到class文件的常量池JVM为每一个装载的类和接口保存一份独立的常量池。来自相同方法或不同方法中的几条指令,可能指向同一个常量池入口。每个常量池入口只被解析一次。解析在程序运行的某些时刻,如果某个特定的符号引用将要被使用,它首先要被解析。解析过程就是根据符号引用查找到实体,在把符号引用替换成直接引用的过程。所有的符号引用都保持在常量池,所以这

16、个过程也被称作常量池解析。解析分为早解析和迟解析。9垃圾收集10栈和局部变量操作StackandLocalVariableOperations10.1 常量入栈操作PushingConstantsOntotheStack10.1.1 将一个字长的常量压入栈OpcodeOperand(s)Descriptioniconst_m1(none)pushesint-1ontothestackiconst_0(none)pushesint0ontothestackiconst_1(none)pushesint1ontothestackiconst_2(none)pushesint2ontothestac

17、kiconst_3(none)pushesint3ontothestackiconst_4(none)pushesint4ontothestackiconst_5(none)pushesint5ontothestackfconst_0(none)pushesfloat0ontothestackfconst_1(none)pushesfloat1ontothestackfconst_2(none)pushesfloat2ontothestack10.1.2 将一个字长的常量压入栈longanddoublevaluesoccupy64bits.Eachtimealongordoubleispush

18、edontothestack,itsvalueoccupiestwoslotsonthestack.long和double类型的值是64位长度的值,每当一个long或者double类型的值被压入栈,将占据2个位置OpcodeOperand(s)Descriptionlconst_0(none)pusheslong0ontothestacklconst_1(none)pusheslong1ontothestackdconst_0(none)pushesdouble0ontothestackdconst_1(none)pushesdouble1ontothestack10.1.3 将空的对象引用(

19、null)压入栈opcode,Oneotheropcodepushesanimplicitconstantvalueontothestack.Theaconst_nullpushesanullobjectreferenceontothestack.OpcodeOperand(s)Descriptionaconst_null(none)pushesanullobjectreferenceontothestack10.1.4 将byte和short类型常量压入栈PushingbyteandshortconstantsontothestackOpcodeOperand(s)Descriptionbi

20、pushbyte1expandsbyte1(abytetype)toanintandpushesitontothestack将byte1(数据典型为byte)转换为int然后将其压入栈sipushbyte1,byte2expandsbyte1,byte2(ashorttype)toanintandpushesitontothestack将byte1和byte2(数据典型为short)转换为int然后将其压入栈10.1.5 将常量池入口压入栈PushingconstantpoolentriesontothestackOpcodeOperand(s)Descriptionldcindexbyte1

21、pushessingle-wordvaluefromconstantpoolentryspecifiedbyindexbyte1ontothestackldc_windexbyte1,pushessingle-wordvaluefromconstantpoolentryindexbyte2specifiedbyindexbyte1,indexbyte2ontothestackldc2_windexbyte1,pushesdual-wordvaluefromconstantpoolentryindexbyte2specifiedbyindexbyte1,indexbyte2ontothestac

22、k10.2 通用栈操作GenericStackOperations10.2.1 栈操作StackmanipulationOpcodeOperand(s)Descriptionnop(none)donothingpop(none)popthetopwordfromtheoperandstackpop2(none)popthetoptwowordsfromtheoperandstackswap(none)swapthetopoperandstacktwowordsdup(none)duplicatetopoperandstackworddup2(none)duplicatetoptwooperan

23、dstackwordsdup_x1(none)duplicatetopoperandstackwordandputtwodowndup_x2(none)duplicatetopoperandstackwordandputthreedowndup2_x1(none)duplicatetoptwooperandstackwordsandputthreedowndup2_x2(none)duplicatetoptwooperandstackwordsandputfourdown10.3 把局部变量压入栈PushingLocalVariablesOntotheStack10.3.1 将1个字长的局部变

24、量压入栈Pushingsingle-wordlocalvariablesontothestackOpcodeOperand(s)Descriptioniloadvindexpushesintfromlocalvariablepositionvindexiload_0(none)pushesintfromlocalvariablepositionzeroiload_1(none)pushesintfromlocalvariablepositiononeiload_2(none)pushesintfromlocalvariablepositiontwoiload_3(none)pushesintf

25、romlocalvariablepositionthreefloadvindexpushesfloatfromlocalvariablepositionvindexfload_0(none)pushesfloatfromlocalvariablepositionzerofload_1(none)pushesfloatfromlocalvariablepositiononefload_2(none)pushesfloatfromlocalvariablepositiontwofload_3(none)pushesfloatfromlocalvariablepositionthree10.3.2

26、将2个字长的局部变量压入栈Pushingdual-wordlocalvariablesontothestackOpcodeOperand(s)Descriptionlloadvindexpusheslongfromlocalvariablepositionsvindexand(vindex+1)lload_0(none)pusheslongfromlocalvariablepositionszeroandonelload_1(none)pusheslongfromlocalvariablepositionsoneandtwolload_2(none)pusheslongfromlocalvar

27、iablepositionstwoandthreelload_3(none)pusheslongfromlocalvariablepositionsthreeandfourdloadvindexpushesdoublefromlocalvariablepositionsvindexand(vindex+1)dload_0(none)pushesdoublefromlocalvariablepositionszeroandonedload_1(none)pushesdoublefromlocalvariablepositionsoneandtwodload_2(none)dload_3(none

28、)pushesdoublefromlocalvariablepositionstwoandthreepushesdoublefromlocalvariablepositionsthreeandfour10.3.3 将对象引用局部变量压入栈Table10-9.PushingobjectreferencelocalvariablesontothestackOpcodeOperand(s)Descriptionaloadvindexpushesobjectreferencefromlocalvariablepositionvindexaload_0(none)pushesobjectreferenc

29、efromlocalvariablepositionzeroaload_1(none)pushesobjectreferencefromlocalvariablepositiononeaload_2(none)pushesobjectreferencefromlocalvariablepositiontwoaload_3(none)pushesobjectreferencefromlocalvariablepositionthree10.4 弹由栈顶部元素,将其赋给局部变量PoppingtoLocalVariables10.4.1 弹由一个字长的值,将其赋给局部变量Poppingsingle-

30、wordvaluesintolocalvariablesOpcodeOperand(s)Descriptionistorevindexpopsinttolocalvariablepositionvindexistore_0(none)popsinttolocalvariablepositionzeroistore_1(none)popsinttolocalvariablepositiononeistore_2(none)popsinttolocalvariablepositiontwoistore_3(none)popsinttolocalvariablepositionthreefstore

31、vindexpopsfloattolocalvariablepositionvindexfstore_0(none)popsfloattolocalvariablepositionzerofstore_1(none)popsfloattolocalvariablepositiononefstore_2(none)popsfloattolocalvariablepositiontwofstore_3(none)popsfloattolocalvariablepositionthree10.4.2 弹由2个字长的值,将其赋给局部变量Poppingdual-wordvaluesintolocalva

32、riablesOpcodeOperand(s)Descriptionlstorevindexpopslongtolocalvariablepositionsvindexand(vindex+1)lstore_0(none)popslongtolocalvariablepositionszeroandonelstore_1(none)popslongtolocalvariablepositionsoneandtwolstore_2(none)popslongtolocalvariablepositionstwoandthreelstore_3(none)popslongtolocalvariab

33、lepositionsthreeandfourdstorevindexpopsdoubletolocalvariablepositionsvindexand(vindex+1)dstore_0(none)popsdoubletolocalvariablepositionszeroandonedstore_1(none)popsdoubletolocalvariablepositionsoneandtwodstore_2(none)popsdoubletolocalvariablepositionstwoandthreedstore_3(none)popsdoubletolocalvariabl

34、epositionsthreeandfour10.4.3 弹由对象引用,将其赋给局部变量PoppingobjectreferencesintolocalvariablesOpcodeOperand(s)Descriptionastorevindexpopsobjectreferencetolocalvariablepositionvindexastore_0(none)popsobjectreferencetolocalvariablepositionzeroastore_1(none)popsobjectreferencetolocalvariablepositiononeastore_2(

35、none)popsobjectreferencetolocalvariablepositiontwoastore_3(none)popsobjectreferencetolocalvariablepositionthree10.5 wide指令ThewideInstruction10.5.1 弹由对象引用,将其赋给局部变量Poppingobjectreferencesintolocalvariables无符号8位局部变量索引,把方法中的局部变量限制在256以下。一条单独的wide指令,可将8位的索引再扩展8位。这样就可以把局部变量的限制扩展到65536OpcodeOperand(s)Descr

36、iptionwideiload,indexbyte2indexbyte1,pushesintfromlocalvariablepositionindexwidelload,indexbyte2indexbyte1,pusheslongfromlocalvariablepositionindexwidefload,indexbyte2indexbyte1,pushesfloatfromlocalvariablepositionindexwidedload,indexbyte1,pushesdoublefromlocalvariablepositionindexbyte2indexwidealoa

37、d,indexbyte1,pushesobjectreferencefromlocalvariableindexbyte2positionindexwideistore,indexbyte1,popsinttolocalvariablepositionvindexindexbyte2widelstore,indexbyte2indexbyte1,popslongtolocalvariablepositionindexwidefstore,indexbyte2indexbyte1,popsfloattolocalvariablepositionindexwidedstore,indexbyte2

38、indexbyte1,popsdoubletolocalvariablepositionindexwideastore,indexbyte1,popsobjectreferencetolocalvariablepositionindexbyte2index11类型转换TypeConversion11.1 longs,floats,anddoubles类型之间的转换Convertingints,longs,floats,anddoublesOpcodeOperand(s)Descriptioni2l(none)convertsinttolongi2f(none)convertsinttofloa

39、ti2d(none)convertsinttodoublel2i(none)convertslongtointl2f(none)convertslongtofloatl2d(none)convertslongtodoublef2i(none)convertsfloattointf2l(none)convertsfloattolongf2d(none)convertsfloattodoubled2i(none)convertsdoubletointd2l(none)convertsdoubletolongd2f(none)convertsdoubletofloat11.2 int数据类型向byt

40、e,char,short类型的转换Convertingints,bytes,chars,andshorts.Noopcodesexistthatconvertdirectlyfromalong,float,ordoubletothetypessmallerthanintJava虚拟机中没有把long,float,ordouble类型值直接转换成比int类型占据更小的空间的数据类型的操作码。Thereforeconvertingfromafloattoabyte,forexample,requirestwosteps.Firstthefloatmustbeconvertedtoanintwith

41、f2i,thentheresultingintcanbeconvertedtoabytewithi2b.因此,把float类型值转换为byte类型需要两个步骤,首先,float类型值必须通过指令转换为int类型值,然后,所得的int值,再通过i2b指令转换为byte类型值Althoughopcodesexistthatconvertaninttoprimitivetypessmallerthanint(byte,short,andchar),noopcodesexistthatconvertintheoppositedirection.Thisisbecauseanybytes,shorts,

42、orcharsareeffectivelyconvertedtointbeforebeingpushedontothestack.尽管有操作码可以把int类型的值转换为比int类型值占据更小空间的数据类型(byte,short,andchar),但并不存在执行相反方向转换操作的操作码,因为任何byte,short,andchar类型值在压入栈的时候,就已经有效的被转换成int类型值了。Arithmeticoperationsuponbytes,shorts,andcharsaredonebyfirstconvertingthevaluestoint,performingthearithmeti

43、coperationsontheints,andbeinghappywithanintresult.涉及bytes,shorts,andchars类型的运算操作首先会把这些值转换成int类型,然后对int类型的值进行计算,最后得到int类型的结果。OpcodeOperand(s)Descriptioni2b(none)convertsinttobytei2c(none)convertsinttochari2s(none)convertsinttoshort12整数运算IntegerArithmetictwo'scomplement补码Allintegertypessupportedby

44、theJavaVirtualMachine-bytes,shorts,ints,andlongs-aresignedtwo's-complementnumbers.Java虚拟机支持的所有整数类型,bytes,shorts,ints,andlongs,他们都是带符号的二进制补码数。Thetwo's-complementschemeallowsbothpositiveandnegativeintegerstoberepresented.二进制补码方案,既能描述正整数,又能描述负整数Themostsignificantbitofatwo's-complementnumber

45、isitssignbit.Thesignbitisonefornegativenumbersandzeroforpositivenumbersandforthenumberzero.符号位为1表示负整数,符号为0表示表示正整数和数字0Thenumberofuniquevaluesthatcanberepresentedbythetwo's-complementschemeistworaisedtothepowerofthetotalnumberofbits能被二进制补码方案表示的数的范围为:2的总位数次募Forexample,theshorttypeinJavaisa16-bitsig

46、nedtwo's-complementinteger.Thenumberofuniqueintegersthatcanberepresentedbythisschemeis216,or65,536.例如,short在java中是16位的带符号的二进制补码整数,能够唯一表示的整数为216,或者65,536Halfoftheshorttype'srangeofvaluesareusedtorepresentzeroandpositivenumbers;theotherhalfoftheshorttype'srangeareusedtorepresentnegativenum

47、bers.Short类型值范围的一半用来表示0和正整数,另一般用来表示负整数。Therangeofnegativevaluesfora16-bittwo's-complementnumberis-32,768(0x8000)to-1(0xffff).Zerois0x0000.Therangeofpositivevaluesisone(0x0001)to32,767(0x7fff).16位2进制补码负数的范围是-32,768(0x8000)to-1(0xffff).0用0x0000来表示.正整数的范围是(0x0001)to32,767(0x7fff).Positivenumbersare

48、intuitiveinthattheyaremerelythebasetworepresentationofthenumber.Negativenumberscanbecalculatedbyaddingthenegativenumbertotworaisedtothepowerofthetotalnumberofbits.整数直觉上只不过是数的两种表示法之一。负数可以通过负数和2的某次方哥相加而得出。Forexample,thetotalnumberofbitsinashortis16,sothetwo's-complementrepresentationofanegativenum

49、berinthevalidrangeforashort(-32,768to-1)canbecalculatedbyaddingthenegativenumberto216,or65,536.Thetwo's-complementrepresentationfor-1is65,536+(-1)or65,535(0xffff).Thetwo's-complementrepresentationfor-2is65,536+(-2)or65,534(0xfffe).例如,short类型的长度为16位。因此2进制补码表示法可以通过一个负数和2的16次哥的相加来得到一个有效范围内的负数。-

50、1的二进制补码表示为65,536+(-1)or65,535(0xffff).-2的二进制补码表示为65,536+(-2)or65,534(0xfffe).Additionisperformedontwo's-complementsignednumbersinthesamewayitwouldbeperformedonunsignedbinarynumbers.Thetwonumbersareadded,overflowisignored,andtheresultisinterpretedasasignedtwo's-complementnumber.Thiswillworkas

51、longastheresultisactuallywithintherangeofvalidvaluesforthetype.Forexample,toadd4+(-2),justadd0x00000004and0xfffffffe.Theresultisactually0x100000002,butbecausethereareonly32bitsinanint,theoverflowisignoredandtheresultbecomes0x00000002.在带符号的二进制补码数上进行加法运算,与在无符号二进制数上进行加法运算一样。两个数相加(忽略溢出),结果被解释为一个带符号的二进制补

52、码数。这个过程将在运算结果是该类型的有效范围内的情况下运行。例如要获得4+(-2)的结果,只要把0x00000004and0xfffffffe相加即可.结果是0x100000002,但因为int类型只有32位,于是溢出部分被忽略,结果为0x00000002.0000000000000000000000000000010011111111111111111111111111111110+10000000000000000000000000000010OverflowinintegeroperationsdoesnotthrowanyexceptionintheJavaVirtualMachine

53、.Theresultismerelytruncatedtofitintotheresulttype(eitherintorlong).Forexample,addingints0x7ffffffand1yields0x80000000.ThismeansthattheJavaVirtualMachinewillreportthat2,147,483,647+1=-2,147,483,648,ifthetypeofthevaluesbeingaddedareintsandnotlongs.AsyouprograminJava,youmustkeepinmindthatoverflowcanhap

54、penandmakesureyouchoosetheappropriatetype,intorlong,ineachsituation.IntegerdivisionbyzerodoesthrowanArithmeticException,soyoushouldalsokeepinmindthatthisexceptioncouldbethrownandcatchitifnecessary.Java虚拟机中整数运算的溢出并不会导致抛出异常。其结果只被简单的截断以符合数据类型(或者为int,或者为long)。例如把int值0x7ffffff和1相加,将会得到0x80000000.因此如果相加的值的类型为int而非long,java虚拟机中2,147,483,647+1的结果将是-2,147,483,648。在java中编程时,你必须随时注意可能发生的溢出,必须在每种情况下确认所选择的数据类型(intorlong)是否正确。整数被0除会抛出一个ArithmeticException异常,所以应该时刻牢记此类异常将会抛出,必须在必要的时候捕获异常。Ifyouencounterasituationinwhichlongjustisn'tlongenou

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论