[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

相關文章
相關標籤/搜索