- 1、本文档共27页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
java学习之虚拟机运行时
这里需要区别类变量和实例变量,简单说: 类变量就是静态变量,这个变量是属于类的,在没有类的实例的时候也可以使用这些类变量。一个类的某个类变量只有一份。 实例变量需要在类的实例产生后才能使用的,每个实例的同名实例变量的值可能不同。 解析过程就是在类型的常量池中寻找类、接口、字段和方法的符号引用,把这些符号引用替换成直接引用的过程。 符号引用和字节码中的信息基本类似。 直接引用:比如: 1. 指向类型、类变量和类方法的直接引用可能是指向方法区的本地指针。 a, 类型的直接引用可能简单的指向保存类型数据的方法区中的与实现相关的数据结构。 b, 类变量的直接引用可以指向方法区中保存的类变量的值。 c, 类方法的直接引用可以指向方法区中一段数据结构,可能包含:是否为本地方法的标识信息,如果是本地方法,就会包含一个指向动态链接本地方法实现的函数指针;如果不是本地方法,就会包含一个方法的字节码、操作数栈空间的最大值、局部变量空间的最大值等信息。 2. 指向实例变量和实例方法的直接引用都是偏移量。 a, 实例变量的直接引用可能是从对象的映像算起到这个实例变量位置的偏移量。 b, 实例方法的直接引用可能是到方法表的偏移量。 上面的代码中,类变量e在没有先声明的情况下,被使用了,应该把e的声明语句放到静态语句块的前面。 1. 类的初始化时,如果有类变量初始化语句或者静态语句块,初始化阶段就会调用clinit方法依次按照源代码类变量初始化语句和静态语句块出现的顺序来初始化它们。clinit方法是在编译时由编译器自动写入到字节码中的。只有当类有类变量初始化语句或者静态语句块时才会有clinit方法。 2. 类变量初始化语句和静态语句块是等价的,它们的顺序与源代码中的顺序是一致的,类变量必须保证先声明后使用的原则,否则编译会出错。 3. 实例变量不在类初始化阶段进行初始化,而是在new操作的时候调用其init方法进行初始化。 4. 仅声明而没有初始化的类变量,不会出现在clinit方法中,但是它已经有默认值,该值在准备阶段就赋值的。 package bytecode; public class StaticField { public char character = c; public int integer; public int a = 5; public static int b = 6; public static double c = Math.random()*0.3; public static String d; public static String e = eeee; public static String f; public static int i1 = OtherStaticField.getSize(1); static{ d = e; System.out.println(static block); } public static int i2 = OtherStaticField.getSize(2); public static void main(String agrs[]){ System.out.println(Hello world); } } 1. 实例变量不在类初始化阶段进行初始化,而是执行过程中的new操作的时候调用其init方法进行初始化。 2. 如果没有显示的初始化方法,编译器会给我出一个默认的无参数的初始化方法init,该方法的字节指令中,会对Java源码中的需要初始化的实例变量进行初始化。 3. 实例变量的声明和赋值不需要有顺序关系,可以在Java代码层面先在语句块中使用,后声明。但是在字节码中对其处理的方式是,哪个语句在Java源代码的前面就先执行哪一句。比如上面的实例变量d,字节码中是先执行d=6,然后执行d=66。 4. 仅声明而没有初始化语句的实例变量,不会出现在init方法的字节码中,但是它的默认值在申请内存空间的时候就已经有了。 5. 第一行指令是为了把局部变量区第偏移量为一的this引用压入操作数栈,然后第二行指令是从操作数栈中弹出this引用,并调用this的超类java.lang.Object类的无参构造函数来初始化超类,第三行再把出局部变量区第偏移量为一的this引用压入操作数栈,第四条指令是把字符c压入操作数栈,用于给属性character赋值。。。。 package bytecode; public class StaticField { public final char character = c; public static int staticInt = 5; p
文档评论(0)