Java 中名稱重用相關(guān)問題

名稱重用有時會導(dǎo)致編譯錯誤,但有時卻不會,導(dǎo)致發(fā)生難以發(fā)現(xiàn)的問題,所以一定要注意。
下面將所有的名稱重用情況列出,并附帶例子,在日常的開發(fā)中一定還會遇到類似的問題,希望能有所幫助。
這部分涉及到的靜態(tài)綁定和動態(tài)綁定問題,理解后對于泛型能有更好的理解,相關(guān)筆記請看文末。

  • 重寫(Overriding)
    子類可以重寫其父類中可訪問到的具有相同簽名的所有成員方法[JLS 8.4.8.1]。
    JVM將會根據(jù)實例的運(yùn)行期類型(對象)來選擇要調(diào)用的重寫方法[JLS 15.12.4.4]。
    靜態(tài)方法是無法重寫的,因為重寫的要求是要動態(tài)綁定(對象),而靜態(tài)方法是靜態(tài)綁定(類)。final方法也是無法重寫的,因為使用final的目的就是防止其被重寫。注意,這里說的搜是方法。
    在 JDK 1.5 及以上中使用 @Override 注解,防止將需要重寫的方法錯寫為重載。

    class Base {
      public void f() {}
    }
    class Derived extends Base {
      @Override
      public void f() {} // overrrides Base.f()
    }
    
    
  • 重載(Overloading)
    在一個類中,可以以相同的名稱和不同的簽名來構(gòu)成重載,重載方法的調(diào)用是在編譯階段選定的(類)。
    簽名指的是方法名及參數(shù)列表,返回類型不是簽名的一部分,所以返回類型不同但是簽名相同的重載是無法編譯通過的。
    盡量要確保重載的方法在相同的簽名上有相同的行為。

    class CircuitBreaker {
      public void f(int i) { } // int overloading
      public void f(String s) { } // String overloading
    }
    
  • 隱藏(Hiding)
    一個成員變量、靜態(tài)方法或成員類型可分別隱藏其父類中可訪問到的具有相同名稱(方法而言是方法簽名)的所有成員變量、靜態(tài)方法或成員類型,隱藏的成員不會被繼承。
    不要去重用 java.lang 包下的類型名。
    補(bǔ)充一下,內(nèi)部成員類的參數(shù)類型(泛型)可以隱藏外部類的參數(shù)類型(這個問題在IDEA中已經(jīng)有溫馨提示)。

    class Base {
        public static String fStr = "base";
    
        public static void f() {System.out.println(fStr); }
    
        static class BaseType {
            public static String type = "base";
        }
    }
    
    class Derived extends Base {
        private static String fStr = "derived"; //hides Base.fStr, even can change the access!
    
        public static void f() { System.out.println(fStr); } // hides Base.f()
    
        //hides Base.BaseType
        static class BaseType {
            public static String type = "derived";
        }
    }
    
  • 遮蔽(Shadowing)
    一個變量、方法或類型可以分別遮蔽在類中具有相同名稱的所有成員變量、成員方法或成員類型。如果一個實體被遮蔽了,根據(jù)實體的不同,有時候根本無法引用到。[JLS 6.3.1]

    class WhoKnows {
      static String sentence = "I don’t know.";
      public static void main(String[] args) {
          String sentence = "I know!"; // shadows static field
          System.out.println(sentence); // prints local variable
      }
    }
    
    //最常見的遮蔽,不是沒有風(fēng)險,但為慣用法。
    class Belt {
      private final int size;
      public Belt(int size) { // Parameter shadows Belt.size
          this.size = size;
      }
    }
    
    
  • 遮掩(Obscuring)
    一個變量名可以遮掩具有相同名稱的一個類型(類),只要他們屬于同一個作用域。類似的,一個變量或一個引用可以遮掩一個包。遮掩是惟一一種兩個名稱位于不同的名稱空間的名稱重用形式,包括:變量、方法、包或類型。
    按照命名規(guī)范來進(jìn)行命名可以有效防止遮掩的發(fā)生。

    public class Obscure {
      static String System; // Obscures type java.lang.System
      public static void main(String[] args) {
          // Next line won’t compile: System refers to static field
          System.out.println("hello, obscure world!");
      }
    }
    

多態(tài):程序綁定(動態(tài)綁定與靜態(tài)綁定)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,679評論 18 399
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡單原理和應(yīng)用。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 5,205評論 1 114
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對于byte類型而言...
    龍貓小爺閱讀 4,451評論 0 16
  • 我,三十歲了 既沒有活出自己理想的樣子 也沒有活出父母期許的樣子 我,三十歲了 既走不出夢想的圍城 也...
    羽成閱讀 288評論 0 0

友情鏈接更多精彩內(nèi)容