[Java基础]代码块及java反编译

块的做用域:前端

  块(即复合语句)是指一对花括号括起来的若干条简单的java语句。块肯定了变量的做用域。一个块能够嵌套在另外一个块中。可是,在嵌套的两个块中声明同名的变量时应注意,块中变量申明在块外变量以后,会报错(如本例),反之不会(如普通代码块的例子)。java

public class BlockMain {
    public static void main(String[] args)
    {
        int k;
        {
            int k;  //此处在嵌套块中申明了相同变量,出错
              int n;
        }    
    }
}

  java中的代码块分为普通代码块,构造代码块,静态代码块,同步代码块。bootstrap

1.普通代码块sass

   在方法或语句中出现的{}就称为普通代码块。普通代码块和通常的语句执行顺序由他们在代码中出现的次序决定--“先出现先执行”
public class CodeBlock01{
        public static void main(String[] args){
           
             {
                int x=3;
                System.out.println("1,普通代码块内的变量x="+x);    
             }
              
             int x=1;
             System.out.println("主方法内的变量x="+x);
 
             {
                int y=7;
                System.out.println("2,普通代码块内的变量y="+y);    
             }
           }
     }

2.构造代码块函数

     初始化数据域的三种方法:工具

  • 在构造器中设置值;
  • 在申明中赋值;
  • 在初始化代码块中赋值;

   构造代码块:直接在类中定义且没有加static关键字的代码块{}称为构造代码块。构造代码块在建立对象时被调用,每次建立对象都会被调用,而且构造代码块的执行次序优先于类构造函数,以下例代码所示:this

public class CBlock {
    
    public CBlock()//构造函数
    {
        i=300;//构造函数中初始化
    }
    
    public int i=100;//显示初始化变量 
            
    {//构造代码块 
        i=200;//构造代码块中初始化变量
    }
    
}

   从如下几点理解以上代码:spa

  1. java编译器编译一个java源文件的时候,会把成员变量的声明语句提早至一个类的最前端,故i能够在使用(构造函数)以后声明;
  2. 成员变量的初始化工做其实都是在构造函数中执行的;
  3. 一旦通过java编译器编译后,那么构造代码块的代码块就会被移动构造函数中执行,是在构造函数以前执行的,原构造函数的中代码是最后执行的;
  4. 成员变量的显示初始化与构造代码块的代码是按照当前代码的顺序执行的。

   总之,调用构造器初始化数据域的步骤为:code

  1. 全部数据域被初始化为默认值(0、false、null,系统默认的);
  2. 按照在类声明中出现的次序,依次执行全部域初始化语句和初始化块;
  3. 若是构造器第一行调用了第二个构造器,则执行第二个构造器主体;
  4. 执行这个构造器的主体。

3.静态代码块htm

  1. 静态代码块:在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每一个静态代码块只会执行一次。因为JVM在加载类时会执行静态代码块,因此静态代码块先于主方法执行。
  2. 若是类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。
  3. 注意:1) 静态代码块不能存在于任何方法体内。2) 静态代码块不能直接访问静态实例变量和实例方法,须要经过类的实例对象来访问。
  4. 执行顺序:(优先级从高到低。)静态代码块>mian方法>构造代码块>构造方法。其中静态代码块只执行一次,构造代码块在每次建立对象是都会执行。。

   可使用java编写一个没有main方法的”Hello world”程序:

public class BlockMain {
    public static void main(String[] args)
    {
        
    }
    static 
    {
        System.out.println("Hello Word");
    }
}

4.同步代码块

 

5.java反编译

(参考:http://www.365mini.com/page/javap-disassemble-class-file-code.htm

  在Sun公司提供的JDK中,就已经内置了Java字节码文件反编译工具javap.exe(位于JDK安装目录的bin文件夹下)。

  咱们能够在dos窗口中使用javap来反汇编指定的Java字节码文件。在使用javap的相关dos命令以前,你必须确保已经将JDK安装目录\bin添加到环境变量path中。

  接着,咱们就可使用javap来反编译指定的Java字节码文件了。在此以前,咱们先经过javap的帮助命令javap -help查看javap相关指令的用法。

javap-helpimage

  从上述内容咱们能够知道,javap的使用命令格式为javap 选项参数 类名,其中选项参数能够有多个,中间用空格隔开,也能够一个都没有。下面咱们编写以下源代码文件(包名test,类名Person),并将其编译为Person.class字节码文件。

 
 
 
 
  1. package test;
  2. public class Person {
  3.    public Person(String name, int age, boolean gender, String address) {
  4.         this.name = name;
  5.         this.age = age;
  6.         this.gender = gender;
  7.         this.address = address;
  8.     }

  9.     private String name; // private修饰符
  10.     int age; // 默认无访问修饰符(即下面所说的package、friendly)
  11.     protected boolean gender; // protected修饰符
  12.     public String address; // public修饰符

  13.     public String getName() {
  14.         return name;
  15.     }

  16.     public void setName(String name) {
  17.         this.name = name;
  18.     }

  19.     public void sayHi() {
  20.         System.out.println("Hello, my name is " + this.name);
  21.     }
  22. }

   先使用javac将Person.java编译为Person.class,再使用javap命令对Person.class进行反编译:

java-person-class

在执行命令以前,咱们须要将dos窗口的当前工做目录变动为D:\java\test

cd-current-dir

1)使用不带任何选项参数的命令:javap Person—将*.class反编译为*.java源文件

javap-person

javap Personjavap -package Person的显示结果同样,由于-package选项参数是默认的,用于显示package(不带任何访问修饰符,即咱们常说的friendly)、protectedpublic修饰的类或成员。

备注:在dos下进入工做目录D:\java,而后使用命令javap test.Person也能够实现上述操做。下同。

2)使用命令:javap -public Person显示public修饰的类或成员

javap-public-person

与此相似,选项参数-protected用于显示protected以上访问级别(protectedpublic)的类或成员;选项参数-private用于显示private以上访问级别,也就是全部的类或成员。

3)使用命令:javap -public -l Person显示public修饰的类或成员,并显示行号表格和本地变量表格

javap-public-l-person

4)使用命令:javap -c Person显示Person.class反汇编出的字节码命令

javap-c-person

因为选项参数之间组合较多,所以其余选项参数再也不一一截图赘述,仅在下面使用文字进行说明:

-classpath <pathlist>
手动指定用户class字节码文件的存放目录,javap程序将在此目录下查找class文件,多个路径以英文分号分隔。例如:javap -classpath D:\java\test Person(即便DOS窗口的当前工做目录为其余任意路径,该命令都可正确执行)。
-s
打印变量的内部类型签名,例如:javap -classpath D:\java\test -s Person。
-extdirs <dirs>
指定javap搜索已安装的java扩展的位置,默认的java扩展的位置为jre\lib\ext。例如:javap -classpath D:\java\test -extdirs D:\java\myext Person
-bootclasspath <pathlist>
指定使用Java底层类加载器(bootstrap class loader)加载的字节码文件的位置。例如:javap -classpath D:\java\test -bootclasspath D:\java\core Person
-verbose
打印方法参数和本地变量的数量以及栈区大小。
-J<flag>
使用javap.exe来执行java.exe虚拟机的相关命令,例如javap -J-version至关于java -version,能够有多个命令,中间以空格隔开。

6.使用反编译理解代码块

   有以下代码块,用反编译查看代码的执行顺序:

package ConstructBlock;

public class CBlock {
    public static void  main(String[] args)
    {
        CBlock cBlock=new CBlock();
        System.out.println(cBlock.i);
            
        int pt=100;
        {
            pt=200;
        }
        
    }
    
    public CBlock()
    {
        i=300;
    }
    
    public int i=100;
            
    {
        i=200;//构造代码块
    }
    
}

使用 javap –c –l –private CBlock进行反编译,由结果能够看出执行顺序是100,200,300,最后输出300;

image

相关文章
相关标签/搜索