【Java面試高頻】i++和++i的區別,單例模式的多種實現以及區別,類和例項初始化順序,不看血虧

炒冷飯發表於2020-10-27

1.i++和++i的區別

image-20201026170404151

分為區域性變數表和運算元棧

i++和++i的操作是直接修改的是區域性變數表中的值

2.單例模式

要點:

  1. 一個類只能有一個例項
    • 私有化構造器
  2. 該單例類必須自主的建立這個例項
    • 該類必須有一個靜態變數來儲存這個例項
  3. 該類需要自行的向整個系統提供這個例項
    • 直接暴露
    • 呼叫靜態變數的get方法

餓漢式:直接建立出這個類的單例,不管需不需要使用

  • 直接例項化餓漢式(簡介直觀)
public class Singleton1 {
    //靜態變數儲存這個類的單例
    public static final Singleton1 INSTANCE = new Singleton1();
    //私有化構造器
    private Singleton1(){

    }
}

  • 列舉式
public enum Singleton2 {
    INSTAANCE
}
  • 靜態程式碼塊的方式
/**
 * 使用靜態程式碼塊的方式建立單例模式
 */
public class Singleton3 {
    public static final Singleton3 INSTANCE ;
    static {
        INSTANCE = new Singleton3();
    }
    private Singleton3(){
        
    }
}

懶漢式:需要的時候再建立該類的單例,不需要就不建立

  • 執行緒不安全的方式(適用於單執行緒的情況)
public class Singleton4 {
    static  Singleton4 INSTANCE;
    private Singleton4(){

    }
    public static Singleton4 getInstance(){
        if (INSTANCE ==null){
            INSTANCE = new Singleton4();
        }
        return INSTANCE;
    }
}
  • 執行緒安全的方式(適用於多執行緒的情況)
/**
 * @author 雷雨
 * @date 2020/10/26 18:49
 */
public class Singleton5 {
    static Singleton5 INSTANCE;
    private Singleton5(){

    }
    public static Singleton5 getInstance(){
        //為了效率
        if (INSTANCE ==null){
            //為了執行緒安全
            synchronized (Singleton5.class){
                if (INSTANCE ==null){
                    INSTANCE = new Singleton5();
                }
            }
        }
        return INSTANCE;
    }
}

3.類初始化順序

由父及子,靜態先行,由上到下

  • 有main方法的類優先初始化,但是如果該類是子類,那需要先初始化其父類
  • 靜態分為:靜態變數和靜態程式碼塊,如果既有靜態變數又有靜態程式碼塊,那麼誰的位置靠上,誰先初始化

類初始化方法就是執行< clinit >()方法

4.例項初始化順序

例項初始化方法就是執行< init >()方法

  • < init >()方法可能過載有多個,有幾個構造器就有幾個< init >()方法
  • < init >()方法由非靜態例項變數顯示賦值程式碼和非靜態程式碼塊,對應構造器程式碼組成

順序:

  • 非靜態例項變數顯示賦值程式碼和非靜態程式碼塊程式碼從上到下順序執行,而對應的構造器的程式碼最後執行
  • 每次建立例項物件,呼叫對用構造器,執行的就是對應的< init >()方法
  • 除此之外如果該類是子類,那麼父類的相關例項初始化先執行

也就是說:

子類的例項初始化方法:

  1. super()
  2. 順序執行子類的非靜態變數顯示賦值語句和非靜態程式碼塊
  3. 子類的無參構造

影響初始化順序的還有:重寫方法

  • 非靜態方法前面有一個預設的物件this
  • this在構造器(< init >()),它表示正在建立的物件,如果此時建立的是子類的物件,那麼執行的就是子類的非靜態方法

哪些方法不能被重寫?

  1. final方法
  2. 靜態方法
  3. private等子類中不可見的方法

重寫和過載的區別和聯絡?

重寫的要求

  • 方法名
  • 形參列表
  • 返回值型別
  • 丟擲的異常
  • 修飾符

時建立的是子類的物件,那麼執行的就是子類的非靜態方法

哪些方法不能被重寫?

  1. final方法
  2. 靜態方法
  3. private等子類中不可見的方法

重寫和過載的區別和聯絡?

重寫的要求(和下面這些是否有關係,有什麼關係,希望讀者能夠自己也想一想)

  • 方法名
  • 形參列表
  • 返回值型別
  • 丟擲的異常
  • 修飾符

我是一名普二本的軟體工程專業學生,秋招中拿到了一些offer,但是自己想要衝擊一下自己的極限,所以在春招之前再總結一下,給自己補充補充能量,查漏補缺。

如果本文對您有益,強烈建議關注我的專欄或者部落格

相關文章