您的位置:首页 > 编程语言 > Java开发

运用实例理解java对象操作

2010-10-09 17:17 666 查看
相信学java的人都对new Object();创建对象都很熟悉,但想要真正了解原理就没那么容易!以以下例子为例,解释class代码及执行过程,如有错误,还望各位高手多多指教!

public class Dog {
public String name;
public int age;
public Dog() {
}
public Dog(String name)
{
this.name = name;
}
public Dog(String name, int age)
{
this.name = name;
this.age = age;
}
public static void  getStaticValue(int j)
{
int i=j;
System.out.println(i);
}
public  void  getValue(int j)
{
int i=j;
System.out.println(i);
}
public static void main(String[] args) {
try {
new Dog().getValue(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如上代码很简单,main方法加上try catch只是为了  让大家看一下java文件生产字节码是怎么样的
执行javac  Dog.java文件,生成class文件。然后使用javap -verbose Dog反编译出class代码。
生成如下代码:
view plaincopy to clipboardprint?
Compiled from "Dog.java"
public class Dog extends java.lang.Object
SourceFile: "Dog.java"
minor version: 0   // minor version: major version:这两个是表示class文件的版本号,
major version: 50   //详细见http://blog.csdn.net/xiaxiaorui2003/archive/2009/07/07/4327029.aspx这位兄弟的blog

Constant pool:      //常量池,如下以const开头的都是常量池信息,每个class文件都有一些常量池信息
//当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用
//如下以#开头的表示偏移量编号,相当于id号,接下来解释如下代码的作用

如下 #11.#31; 这段代码什么作用呢?很简单,就是表示创建Object对象。
首先来看.号左边的#11,找到常量池中#11,跳到const #11 = class       #42;    //  java/lang/Object
这个表示是一个Object类型,class后面的 #42;表示接下来要跳到常量池中#42
找到const #42 = Asciz       java/lang/Object;  表示生成Object类型
接下来看.号右边的#31。
const #31 = NameAndType #16:#17;     //解释:这里指定到#16 #17
const #16 = Asciz       <init>;
const #17 = Asciz       ()V;      //解释:到这里完成初始化工作

//NameAndType表示名字和类型   调用构造方法 的Name都是<init>,   V表示没有返回值     ,()  括号里面是空的表示没有参数
//到这里完成Dog
//
如下有  :
Method   //方法
Field   //类名.属性
class   //类型
Asciz   //方法签名
NameAndType   //变量名和类型

java类型对应的class文件方法签名的标识符:
invokespecial  //调用构造方法、父类方法
invokevirtual  //调用普通方法(非构造方法、static方法)
invokestatic   //调用static方法

Ljava/lang/String;;  //这表示String类型,这里要全路径,java/lang/String;;前面的L表示非java八大基本类型
void V
int char byte short long float double 都是类型第一个字母(大写)
boolean 比较特别,用J表示  ,因为B被byte给占用了

const #1 = Method       #11.#31;        //  java/lang/Object."<init>":()V     解释:初始化Object

const #2 = Field        #6.#32; //  Dog.name:Ljava/lang/String;      Dog类中定义的String name
const #3 = Field        #6.#33; //  Dog.age:I        Dog类中定义的int age
const #4 = Field        #34.#35;        //  java/lang/System.out:Ljava/io/PrintStream;
const #5 = Method       #36.#37;        //  java/io/PrintStream.println:(I)V      解释:调用println(int value), V表示返回值是void
const #6 = class        #38;    //  Dog
const #7 = Method       #6.#31; //  Dog."<init>":()V     解释:初始化Dog,调用构造函数,"<init>"是初始化标识符, V表示返回值是void
const #8 = Method       #6.#39; //  Dog.getValue:(I)V      解释:调用getValue(int j)方法, V表示返回值是void
const #9 = class        #40;    //  java/lang/Exception
const #10 = Method      #9.#41; //  java/lang/Exception.printStackTrace:()V
const #11 = class       #42;    //  java/lang/Object
const #12 = Asciz       name;
const #13 = Asciz       Ljava/lang/String;;
const #14 = Asciz       age;
const #15 = Asciz       I;
const #16 = Asciz       <init>;
const #17 = Asciz       ()V;
const #18 = Asciz       Code;
const #19 = Asciz       LineNumberTable;
const #20 = Asciz       (Ljava/lang/String;)V;
const #21 = Asciz       (Ljava/lang/String;I)V;
const #22 = Asciz       getStaticValue;
const #23 = Asciz       (I)V;
const #24 = Asciz       getValue;
const #25 = Asciz       main;
const #26 = Asciz       ([Ljava/lang/String;)V;
const #27 = Asciz       StackMapTable;
const #28 = class       #40;    //  java/lang/Exception
const #29 = Asciz       SourceFile;
const #30 = Asciz       Dog.java;
const #31 = NameAndType #16:#17;//  "<init>":()V
const #32 = NameAndType #12:#13;//  name:Ljava/lang/String;
const #33 = NameAndType #14:#15;//  age:I
const #34 = class       #43;    //  java/lang/System
const #35 = NameAndType #44:#45;//  out:Ljava/io/PrintStream;
const #36 = class       #46;    //  java/io/PrintStream
const #37 = NameAndType #47:#23;//  println:(I)V
const #38 = Asciz       Dog;
const #39 = NameAndType #24:#23;//  getValue:(I)V
const #40 = Asciz       java/lang/Exception;
const #41 = NameAndType #48:#17;//  printStackTrace:()V
const #42 = Asciz       java/lang/Object;
const #43 = Asciz       java/lang/System;
const #44 = Asciz       out;
const #45 = Asciz       Ljava/io/PrintStream;;
const #46 = Asciz       java/io/PrintStream;
const #47 = Asciz       println;
const #48 = Asciz       printStackTrace;

{
public java.lang.String name;

public int age;

//如下的Locals表示方法内局部变量个数,该例中是1,有些人疑惑的是Dog()中明明没有参数啊,应该是0啊!
//当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用
//非static方法,在调用的时候都会给方法默认加上一个当前对象(this)类型的参数,不需要在方法中定义,
//这个时候局部变量列表中index为0的位置保存的是this,其他索引号按变量定义顺序累加
//static方法不依赖对象,所以不用传this
//Args_size表示参数个数,public Dog();会传一个this进去,所以value是1
public Dog();
Code:
Stack=1, Locals=1, Args_size=1
0:   aload_0    //加载局部变量表index为0的变量,在这里是this
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V      //调用构造方法
4:   return
LineNumberTable:
line 6: 0
line 7: 4

//这个构造方法与上个构造方法也是同理,只是多少个String参数和  给name赋值
public Dog(java.lang.String);
Code:
Stack=2, Locals=2, Args_size=2
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
//这里的#1;表示对常量池的引用,创建一个类,必须先初始化父类,创建Dog之前创建Object
4:   aload_0     //加载局部变量表index为0的变量,在这里是this
5:   aload_1     //加载局部变量表index为1的变量,在这里是String name局部变量
6:   putfield        #2; //Field name:Ljava/lang/String;   赋值操作
9:   return
LineNumberTable:
line 10: 0
line 11: 4
line 12: 9

public Dog(java.lang.String, int);
Code:
Stack=2, Locals=3, Args_size=3
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
4:   aload_0
5:   aload_1
6:   putfield        #2; //Field name:Ljava/lang/String;
9:   aload_0
10:  iload_2
11:  putfield        #3; //Field age:I
14:  return
LineNumberTable:
line 15: 0
line 16: 4
line 17: 9
line 18: 14

//这里的Args_size=1,是因为是static方法,不会传进this
public static void getStaticValue(int);
Code:
Stack=2, Locals=2, Args_size=1
0:   iload_0
1:   istore_1     //istore_1其实是是有两部分组成,i表示int类型 ,1表示局部变量表中index为1。那合起来就是存储在局部变量表中,index为1的位置
2:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;         //引用常量池 #4;
5:   iload_1
6:   invokevirtual   #5; //Method java/io/PrintStream.println:(I)V     //引用常量池 #5;
9:   return
LineNumberTable:
line 21: 0
line 22: 2
line 23: 9

public void getValue(int);
Code:
Stack=2, Locals=3, Args_size=2
0:   iload_1
1:   istore_2
2:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
5:   iload_2
6:   invokevirtual   #5; //Method java/io/PrintStream.println:(I)V
9:   return
LineNumberTable:
line 26: 0
line 27: 2
line 28: 9

public static void main(java.lang.String[]);
Code:
Stack=2, Locals=2, Args_size=1
0:   new     #6; //class Dog       解释:创建Dog
3:   dup       //复制引用到stack(栈)
4:   invokespecial   #7; //Method "<init>":()V
7:   bipush  10      //压入一个常量10
9:   invokevirtual   #8; //Method getValue:(I)V
12:  goto    20
15:  astore_1
16:  aload_1
17:  invokevirtual   #10; //Method java/lang/Exception.printStackTrace:()V
20:  return
Exception table:
from   to  target type
0    12    15   Class java/lang/Exception  //表示上面代码从1到12行之间如果发生Exception异常就goto到15处

LineNumberTable:
line 32: 0
line 35: 12
line 33: 15
line 34: 16
line 36: 20

//如下这块我不太理解什么意思,加了try catch之后才出现这个的,还有如上的 Stack=    ,
//这个不知道是什么意思,暂没有领悟 ,望高手指导
StackMapTable: number_of_entries = 2
frame_type = 79 /* same_locals_1_stack_item */
stack = [ class java/lang/Exception ]
frame_type = 4 /* same */

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐