官术网_书友最值得收藏!

3.1 Java語(yǔ)法深入講解

本節(jié)對(duì)Java語(yǔ)法中一些高級(jí)主題進(jìn)行講解。

3.1.1 static

1.static變量

本質(zhì)上講,static關(guān)鍵字聲明了一個(gè)全局變量。

盡管Java是一門純面向?qū)ο蟮恼Z(yǔ)言,語(yǔ)言規(guī)范中沒有全局變量這種說法,但static聲明的變量,從本質(zhì)上就等同于C或C++語(yǔ)言中的全局變量。整個(gè)應(yīng)用程序只有一個(gè)變量實(shí)例,任何對(duì)static變量進(jìn)行的更改,在程序的其他地方都可見。

舉個(gè)例子如下:

        public class StaticExample {
            public static int counter;
        }

counter是個(gè)整型變量,前面用static關(guān)鍵字修飾后,就變成了一個(gè)全局變量,在程序的代碼執(zhí)行之前,這個(gè)counter變量就已經(jīng)存在于內(nèi)存中了,而且是唯一的實(shí)例。

counter靜態(tài)變量是在StaticExample類中聲明的,但實(shí)際上counter變量是獨(dú)立于StaticExample的任何實(shí)例的。也就是說,程序沒有創(chuàng)建任何StaticExample實(shí)例時(shí), counter已經(jīng)存在。程序創(chuàng)建100個(gè)StaticExample實(shí)例時(shí),couner在內(nèi)存中仍然是一個(gè),而不是100個(gè)。當(dāng)程序中創(chuàng)建的StaticExample類的實(shí)例都被虛擬機(jī)垃圾回收了, counter還存在。因此靜態(tài)變量的生命周期,可以認(rèn)為程序的第一行代碼執(zhí)行之前,就已經(jīng)在內(nèi)存中準(zhǔn)備好,在程序的最后一行代碼執(zhí)行完畢,靜態(tài)變量還存在于內(nèi)存中。靜態(tài)變量獨(dú)立于任何對(duì)象,包括聲明靜態(tài)變量的類實(shí)例對(duì)象。

對(duì)簡(jiǎn)單類型是這樣,對(duì)復(fù)雜類型(對(duì)象類型)也是這樣。

靜態(tài)變量的這種特性,經(jīng)常被用在單實(shí)例的類實(shí)現(xiàn)中,例子如下:

                  public class Logger {
                      // 構(gòu)造函數(shù)聲明為private, 這樣就不能在類的外部用new 來創(chuàng)建對(duì)象
                      private Logger() {}
                      private static Logger logger=null;    // 單實(shí)例
                      // 暴露給外界調(diào)用的方法
                      public static Logger getLogger() {
                          if(null==logger){ // 判斷靜態(tài)實(shí)例是否初始化,如沒有就創(chuàng)建
                              logger=new Logger();
                          }
                          return logger; // 返回全局唯一的實(shí)例
                      }
                      //……  其他方法聲明
                  }

2.static方法

如果一個(gè)方法,僅依賴方法的傳入?yún)?shù)、其他static變量,則此方法不依賴于聲明方法的類實(shí)例,應(yīng)該聲明為static。表示此方法是類方法,而非實(shí)例方法。例子如下:

                  public class ConvertUtil {
            public static int toInt(String s) {
                return Integer.parseInt(s);
            }
        }

toint方法的實(shí)現(xiàn),僅依賴于方法傳入的參數(shù)s,不依賴ConvertUtil對(duì)象的成員變量,因此toint方法是個(gè)類方法,不是個(gè)實(shí)例方法,因此用static來修飾toint方法的聲明。這樣,調(diào)用者調(diào)用時(shí)的代碼就像下面這樣:

            int iValue = ConvertUtil.toInt(str);

如果不用static修飾,則調(diào)用者的代碼就需要修改為如下:

            ConvertUtil util = new ConvertUtil();
            int iValue = util.toInt(str);

但實(shí)際上,toint方法根本就不需要?jiǎng)?chuàng)建一個(gè)ConvertUtil類的實(shí)例,創(chuàng)建這個(gè)對(duì)象是個(gè)浪費(fèi)。

組件設(shè)計(jì)中,常用的工具類方法,基本都是static方式聲明的。

3.static類

一個(gè)普通的Java類聲明,用static修飾,是非法的,編譯器會(huì)提示出錯(cuò)。這一點(diǎn),與C++的靜態(tài)類的概念是完全不同的。在C++中,一個(gè)類的聲明用static修飾,則這個(gè)類中的所有成員變量和成員函數(shù)都是靜態(tài)方法,獨(dú)立于對(duì)象存在。

對(duì)于嵌套類的聲明,可以用static修飾,但這有另外的含義,在后續(xù)的嵌套類中進(jìn)行講解。

3.1.2 嵌套類

一個(gè)類的聲明,是在另外一個(gè)類中,這種在類中聲明的類叫嵌套類,也叫類中類、內(nèi)部類。例子如下:

        public class Outer {
            private String outerId;
                      private Inner inner = new Inner();
                      public String getId() {
                          // 訪問內(nèi)部類的私有成員
                          return outerId + "-" + inner.innerId;
                      }
                      public void setId(String id) {
                          String[] strArray = id.split("-");
                          outerId = strArray[0];
                          inner.setId(strArray[1]);          // 調(diào)用內(nèi)部類的私有方法
                      }
                      private void printStr(String str) {
                          System.out.println(str);
                      }
                      // 內(nèi)部類定義
                      public class Inner {
                          private String innerId;
                          private String getId() { return innerId; }
                          private void setId(String id) {
                              innerId = id;
                          }
                          protected void printId() {
                              String str = "outerId=" + outerId + ", innerId=" + innerId;
                                              // 訪問外部類的私有成員
                              printStr(str);       // 訪問外部類的私有方法
                          }
                      }
                  }

總結(jié)如下:

(1)內(nèi)部類可以訪問外部類的任何成員變量,包括外部類實(shí)例的私有成員變量。

(2)內(nèi)部類可以調(diào)用外部類的任何成員函數(shù),包括外部類實(shí)例的私有成員函數(shù)。

(3)外部類可以訪問內(nèi)部類的任何成員變量,包括內(nèi)部類實(shí)例的私有成員變量。

(4)外部類可以調(diào)用內(nèi)部類的任何成員函數(shù),包括內(nèi)部類實(shí)例的私有成員函數(shù)。

因此,對(duì)于內(nèi)部類的成員變量和成員函數(shù),用private, protected, public, package修飾,就如同沒有這些修飾詞一樣。

另外,內(nèi)部類是不能獨(dú)立于外部類而單獨(dú)存在的,對(duì)象構(gòu)造的順序是由外向內(nèi),先生成外部類,然后生成內(nèi)部類。

3.1.3 靜態(tài)嵌套類

嵌套類,在類聲明的時(shí)候用static修飾,就成了靜態(tài)嵌套類。靜態(tài)嵌套類與普通嵌套類是完全不同的。這里,static的唯一作用,就相當(dāng)于一個(gè)分隔符,將內(nèi)部類和外部類隔離開來,使內(nèi)部類獨(dú)立于外部類單獨(dú)存在。也就是說,內(nèi)部類對(duì)外部類沒有任何的依賴關(guān)系。而普通的內(nèi)部類,是必須依賴于外部類而存在的。

因此,外部類與靜態(tài)內(nèi)部類之間的關(guān)系,就和兩個(gè)獨(dú)立的類之間的關(guān)系相同,二者之間互相訪問,與兩個(gè)獨(dú)立類之間的訪問規(guī)則相同。因此,用private, protected, public, package修飾,將直接影響可訪問性。示例如下:

        public class OuterClass {
            private String outerId;
            private StaticInner inner = new StaticInner();
            public String getId() {
                //return outerId+"-"+inner.innerId(); // 私有成員,不允許訪問
                  return outerId+"-"+inner.getInnerId();// 公有方法,可以訪問
              }
            public void setId(String id) {
                String[] strArray = id.split("-");
                outerId = strArray[0];
                inner.setInnerId(strArray[1]); // 公有方法,可以訪問
                      }
                      private void printStr(String str) {
                          System.out.println(str);
                      }
                      public static class StaticInner {
                          private String innerId;
                          public String getInnerId() {
                              return innerId;
                          }
                          public void setInnerId(String innerId) {
                              this.innerId = innerId;
                          }
                          public void printId() {
                              // 無法訪問外部類的私有成員
                                  // String str = "outerId=" + outerId + ", innerId=" + innerId;
                              //printStr(str);     // 無法訪問外部類的私有方法
                                  OuterClass outer = new OuterClass();
                              outer.printStr(innerId);  // 同一package中,可以訪問私有方法
                          }
                      }
                  }
主站蜘蛛池模板: 南雄市| 夏河县| 卢氏县| 武宣县| 彩票| 贵定县| 吉林省| 苍南县| 郸城县| 毕节市| 凤城市| 河南省| 定边县| 台东县| 湘西| 花莲市| 平利县| 栖霞市| 彭阳县| 科尔| 秦安县| 新民市| 新疆| 湖北省| 融水| 蓬安县| 年辖:市辖区| 玉龙| 保靖县| 舒城县| 桃园市| 十堰市| 襄城县| 灵武市| 梅州市| 巴林右旗| 武威市| 新巴尔虎右旗| 克什克腾旗| 城口县| 怀仁县|