程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 通過內部類的一個例子展示java中的可訪問特性

通過內部類的一個例子展示java中的可訪問特性

編輯:JAVA編程入門知識

       該篇文章涉及到了Java可訪問特性以及內部類的一些內容,向讀者展示了一個內部類的非凡的現象,通過這個例子,使開發者了解到一些他們以前可能沒有注重到的細節,也許可以幫助開發者更透徹的了解java的可訪問特性、內部類和虛擬機。並且通過對這些細節的分析,可能會對開發者思考、分析問題,以及適當的使用工具有所啟迪。
  
  java的訪問修改符(Access modifier)包括:Default-Access、public、private、protected四種。並不是所有的情況都可以使用全部四種訪問修改符,有的情況下使用某些訪問修改符是沒有意義的,例如:假如一個類不是內部類,則不能使用private作為該類的訪問修改符,編譯下面的代碼:
  private class test
  { ... }
  jdk編譯器將給出“modifier private not allowed here”錯誤提示。因為private特性只能由定義它的那個類使用,假如上面的代碼通過編譯,則不會有任何情況可以使用test類,那麼也就不會有任何意義。
  
  假如一個類沒有定義任何構造函數,則編譯器將生成一個缺省的構造函數,該構造函數的訪問修改符和類的訪問修改符相同,例如:
  class test將生成test()構造函數public class test將生成public test()構造函數。
  在使用內部類的情況,上述的特性將使編譯器表現出一個非凡現象。需要說明的是,下面的例子僅針對Windows系統下jdk編譯器,作者並沒有嘗試使用其他的編譯器的情況。但由於java編譯器生成的是class文件這種中間形式的代碼,所以下面的討論應該適用於任何符合java標准的編譯器。
  編譯下面的代碼:
  public class Wrapper
  {
  private class InnerClass
  {}
  
  private void testInnerClass()
  {
  InnerClass inner = new InnerClass();
  }
  
  public static void main(String[] args)
  {
  Wrapper wrapper = new Wrapper();
  wrapper.testInnerClass();
  }
  }
  將產生三個class文件:Wrapper、Wrapper$InnerClass和Wrapper$1。
  對於前兩個文件,了解內部類的讀者都會理解,但第三個類Wrapper$1的作用是什麼呢?
  使用java的反射機制,或者使用javap反匯編器,將發現Wrapper$1類沒有任何成員變量和方法,而Wrapper$InnerClass則除了有一個private Wrapper$InnerClass()構造方法外,還有一個Wrapper$InnerClass(Wrapper$1)構造方法,使用javap,你將發現Wrapper$InnerClass(Wrapper$1)並沒有使用Wrapper$1類型的參數,而只是直接調用了private Wrapper$InnerClass()。假如讀者仔細思考一下創建一個新的類實例的過程,大概已經明白了產生上述現象的原因:當程序試圖創建一個Wrapper$InnerClass的類實例時,卻不能使用其缺省的構造函數,因為Wrapper$InnerClass()是private的,不能由外部使用。因此編譯器不得不再生成一個可訪問的構造函數,由於這裡只有Wrapper類的private void testInnerClass()方法使用了new InnerClass(),所以編譯器只(需)為這個新的構造函數生成了Default-Access的訪問修改符。同時,為了和已有的缺省構造函數有所區別,就加入了一個Wrapper$1類型的參數,為此,編譯器還要生成一個Wrapper$1類。
  
  為了更簡單,(也許)更清楚的看到編譯器生成的class代碼工作的原理,讀者可以使用java反編譯器,來看看class反編譯後生成的java源程序,下面是作者使用Jad反編譯後生成的Wrapper類的代碼:
  // Decompiled by Jad v1.5.7d. Copyright 2000 Pavel Kouznetsov.
  // Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.Html
  // Decompiler options: packimports(3)
  // Source File Name: Wrapper.java
  
  public class Wrapper
  {
  private class InnerClass
  {
  
  private InnerClass()
  {
  }
  
  InnerClass(_cls1 _pcls1)
  {
  this();
  }
  }
  
  public Wrapper()
  {
  }
  
  private void testInnerClass()
  {
  InnerClass innerclass = new InnerClass(null);
  }
  
  public static void main(String args[])
  {
  Wrapper wrapper = new Wrapper();
  wrapper.testInnerClass();
  }
  
  // Unreferenced inner classes:
  
  /* anonymous class */
  class _cls1
  {
  }
  
  }
  
  顯然,Wrapper$1類不會有任何實際的作用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved