Java高级之类结构的认识


        本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!


Java的类结构是对变量,各种访问标记,接口和继承,同步、枚举,注解,内部类,异常、方法等的组合


类文件是以8个字节为基础单位的二进制流


类文件和图片都有魔数,用来标识它可以被虚拟机接受,即0xCafeBabe-全大写,只是为了方便大家记忆;在很多地方都有应用,因为文件后缀名可以改变,而它不能改变。


Java类文件的前4位代表它是否能被虚拟机接受,之后是版本号,5和6代表次版本号,7和8代表主版本号

紧接下来的是常量,大概有11种表结构,除了常见的String,Integer,Float,Double,Long以外,还有Class,Utf-8,Field,Method,InterfaceMethod,NameAndType类型,数量不确定


接着是访问标志有8种,public,final,abstract,interface,super,enum,annotation,synthetic(非用户代码产生的类)


接着是“继承”索引,this索引和super索引,除Object以外,其他索引值均不为0,代表有父类;索引集合描述这个类实现了哪些接口,从左到右按顺序排列,有几个计数器值为几


再接下来是字段表集合,描述所有的变量(如作用范围-public,并变性-final,并发可见-volatile等)和返回值(基本数据类型和类),基本数据类型的全限定名,开头都是其英文大写,如'[()V; '和'[[Ljava/lang/String';前者代表一个空返回值,后者代表一个String二维数组,类都以L开头作表示;全限定名可以理解为对象的地址。


接下来到方法表集合了,跟字段表一样,但某些访问控制答不能修饰方法,如volatile和transient关键字,方法名加尖括号表示,如<init>-指实例构造器,<cinit>-指类构造器,编译后的代码存在一个"Code"的属性里

属性表,类、方法体、常量表中都有属性表

1、Code属性指编译后的字节码,还有它的长度,栈的最大深度,最大存储空间,一个方法编译后不允许超过65535个字节码指令,一个指令=1Slot=32位,这是最小的存储单位,而float和int都是32位;一般还可以分为源码和元数据(即对源码的描述,如类,字段,方法等)

	public static int getFinally() {
		int a = 1;
		try {
			a = 2;
			return a;
		} catch (Exception e) {
			// TODO: handle exception
			a = 3;
			return a;
		} finally {
			a = 4;
		}
	}
上面是用一段源码,来对字节码指令进行分析,很多人看见后,都很想对照自己的结果,准确答案是 2

跟你的结果是否一致,为什么是2而不是4呢?

这段代码可以分为三层来分析:

第一层如果try没有任何问题,则执行a=2 return a

第二层,如果try出错,则执行finally,再执行catch语句,a=3 return a

第三层,如果try无错,catch无错,而出现了其他error,则直接执行finally语句的a=4

这个地方可以这样理想,按照正常的Java指令没有打乱的情况下,先执行try return时已经执行a的write方法,则finally中仅执行了a的assign方法,此时a已经为2。不懂变量加载过程的,可以查看:Java高级之内存模型分析

2、Exceptions属性 列举出可检查出的异常如catch语句后和throws的异常

3、LineNumberTable属性 描写源码行号与字节码行号的关系,即这段代码位于哪一行,用于异常抛出时定位

4、LocalVariableTable属性 定义后别人引用,不会产生参数是arg0,arg1的情况

5、SourceFile属性,用于记录Class源码文件名称,主要异常抛出时可以定位是哪个文件

6、ConstantValue属性,通知虚拟机自动定义为静态变量,只能为基本数据类型和String类型

7、InnerClasses属性 显然定义内部类的,数量位置等

8、Deprecated及Synthetic 前者是定义废弃类,方法,变量等,后者指非源码产生由编译器自动加的东西。


Class文件是虚拟机解释的入口,了解其内部结构,有助于对代码进行分析定位错误,以及热加载等其他功能的理解。


以下是拓展知识


1位=1bit 最小的计算机单位,指0和1

byte=8bit 字节 取值范围 -2^8到2^7 记忆技巧 2^字节次方

char =2byte 0到2^16 Unicode

short=2byte -2^15到2^15-1

int =4byte -2^31到2^31-1

float=4byte

long=8byte -2^63到2^63-1

double=8byte  

boolean 无意义

一个汉字是2位,一个英文字母1位

虚拟机的存存储区域,一般常说的有栈和堆,栈放指针和基本数据类型,而堆放对象,还有一种需要熟悉的是常量存储,就是存代码内部(方法里的);还有两种拓展了解:寄存器位于处理器内部,极少,处理极快;非RAM存储,如持久化对象和流对象,特指数据流传输和硬盘对象。除了常量存储存在只读存储器(ROM-Only)和寄存器,其他都存在随机访问存储器(RAM-Acess)里。

位操作介绍四种,位与(&),位或(|),位否(~)和异或(^)

位与,同为1则为1,否则为0

位或,有一个1则为1,否同为0

位否,1变0,0变1 计算方式~x=-(x+1)

异或,不同则为1,相同则为0

		int a = 0x010101;
		int b = 0x110100;
		System.out.println(a & b);
		System.out.println("位于操作:"+0x010100);
		System.out.println(a | b);
		System.out.println("位或操作:"+0x110101);
		System.out.println(a ^ b);
		System.out.println("异或操作:"+0x100001);
结果

65792
位于操作:65792
1114369
位或操作:1114369
1048577
异或操作:1048577
Tips:负数操作 要先获得补码再操作,然后变源码+1操作


图片的大小=图片width*height*颜色深度

格式有四种(A-Alpha不透明度 R-Red G-Green B-Blue)

ALPHA_8格式  8位=1byte

ARGB_4444格式 16位=4+4+4+4=2byte

RGB_565格式 16位=5+6+5=2byte

ARGB_8888格式 32位=8+8+8+8=4byte

借用格式来压缩图片是一种不错的办法。

以下是摘抄的图片魔数

图像文件头
  1)1-2:(这里的数字代表的是"字",即两个字节,下同)图像文件头。0x4d42='BM',表示是Windows支持的BMP格式。(注意:查ascii表B 0x42,M0x4d,bfType 为两个字节,B为low字节,M为high字节所以bfType=0x4D42,而不是0x424D,但注意)
  2)3-6:整个文件大小。4690 0000,为00009046h=36934。
  3)7-8:保留,必须设置为0。
  4)9-10:保留,必须设置为0。
  5)11-14:从文件开始到位图数据之间的偏移量(14+40+4*(2^biBitCount))。4600 0000,为00000046h=70,上面的文件头就是35字=70字节。

位图信息头

  6)15-18:位图图信息头长度。
  7) 19-22:位图宽度,以像素为单位。8000 0000,为00000080h=128。
  8)23-26:位图高度,以像素为单位。9000 0000,为00000090h=144。
  9)27-28:位图的位面数,该值总是1。0100,为0001h=1。
  10)29-30:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000为0010h=16。
  11)31-34:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3。
  12)35-38:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于(≥位图宽度的最小的4的倍数)×位图高度×每个像素位数。0090 0000为00009000h=80×90×2h=36864。
  13)39-42:用象素/米表示的水平分辨率。A00F 0000为0000 0FA0h=4000。
  14)43-46:用象素/米表示的垂直分辨率。A00F 0000为0000 0FA0h=4000。
  15)47-50:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。
  16)51-54:对图象显示有重要影响的颜色索引的数目。如果是0,表示都重要。 


你可能感兴趣的:(Java高级之类结构的认识)