Hello,你好呀,我是
灰小猿!一個超會寫bug的程式猿!
用堅持締造技術、用指尖敲動未來!
和很多小伙伴們一樣,我也是一名奔波在Java道路上的“創造者”,也想靠技術來改未來,改變世界!因為我們堅信每一次敲動鍵盤都能讓生活變得更智能、世界變得更有趣!
在此專欄《Java核心面試寶典》記錄我們備戰夢想的【day 7】!
上一篇文章和大家分享在面向物件方面的一些常見面試題,但是比較多就只分享了在構造方法和靜態實體方面的題目,今天就繼續來和大家總結剩下的面試題,

1、靜態初始化塊和非靜態初始化塊的執行順序是什么?以及分別會執行多少次?
靜態初始化塊的優先級最高,會最先執行,在非靜態初始化塊之前執行,靜態初始化塊只在類第一次被加載時執行, 非靜態初始化塊會在每次創建物件時執行一次,因此創建了多少個物件,就會執行多少次非靜態初始化塊,
2、靜態初始化塊和main方法哪個先執行?
靜態初始化塊會在類第一次被加載時執行,而main方法是在類中定義的方法,所以靜態初始化塊會在main方法執行之前執行,
3、存在繼承關系的初始化塊的執行順序是怎樣的?
如果存在繼承關系,則在子類進行類加載和創建物件時,也會對父類進行類加載和創建物件,執行順序仍然是靜態初始化塊、非靜態初始化塊、構造器,
如對于兩個類,一個子類一個父類的情況,執行順序如下:
- 執行父類的靜態初始化塊
- 執行子類的靜態初始化塊
- 執行父類的非靜態初始化塊
- 執行父類的構造器
- 執行子類的非靜態初始化塊
- 執行子類的構造器
追問:如果不止兩個類的繼承呢?應該按照什么順序執行?
對于多個類之間的繼承,執行順序如下:
- 按照從父類到子類的順序,依次執行每個類的靜態初始化塊
- 按照從父類到子類的順序,對于每個類,依次執行非靜態初始化塊和構造器,然后執行子類的非靜態初始化塊和構造器,知道所有類執行完畢,
可能邏輯性有些有些強,我通過一個實體代碼給大家演示一下:
以下代碼可以說明初始化塊和構造器的執行順序,代碼中定義了四個類,分別是 Main、Class1、Class2 和 Class3,其中 Class2 是 Class1 的子類,Class3 是 Class2 的子類,每個類都有靜態初始化塊、非靜態初始化塊和構造器,靜態方法 main 定義在 Main 中,創建了 Class3 的實體,
public class Main {
static {
System.out.println("Static initialization of Main");
}
{
System.out.println("Instance initialization of Main");
}
public Test() {
System.out.println("Constructor of Main");
}
public static void main(String[] args) {
new Class3();
}
}
class Class1 {
static {
System.out.println("Static initialization of Class1");
}
{
System.out.println("Instance initialization of Class1");
}
Class1() {
System.out.println("Constructor of Class1");
}
}
class Class2 extends Class1 {
static {
System.out.println("Static initialization of Class2");
}
{
System.out.println("Instance initialization of Class2");
}
Class2() {
System.out.println("Constructor of Class2");
}
}
class Class3 extends Class2 {
static {
System.out.println("Static initialization of Class3");
}
{
System.out.println("Instance initialization of Class3");
}
Class3() {
System.out.println("Constructor of Class3");
}
}
由于沒有創建 Main 的實體,因此 Main 的非靜態初始化塊不會被執行,但是由于程式的入口即靜態方法 main 定義在 Main 中,因此 Main 的靜態初始化塊首先被執行,
在方法 main 中創建了 Class3 的實體,按照父類到子類的順序,依次執行每個類的靜態初始化塊,因此 Class1、Class2 和 Class3 的靜態初始化塊被依次執行,
在所有類的靜態初始化塊被執行之后,按照父類到子類的順序,依次執行每個類的非靜態初始化塊和構造器,因此按照 Class1、Class2 和 Class3 的順序,每個類的非靜態初始化塊和構造器被執行,
4、關鍵字this的含義是什么?
關鍵字this代表當前物件的參考,當前物件指的是呼叫類中的屬性或方法的物件,
5、關鍵字this在方法中以及在構造方法中分別表示什么?
關鍵字this可以用于參考物件的屬性,在方法和構造方法中都可以通過關鍵字this來參考物件的屬性,在構造方法中,通過this還可以參考其他的構造方法,
6、關鍵字this是否可以在靜態方法中使用?說明理由!
關鍵字this不可以在靜態方法中使用,因為關鍵字this代表的是物件的參考,而靜態方法不依賴于類的具體物件,
7、如果類成員不加任何修飾符,可以從哪里訪問到該類成員?
不加任何可見性的修飾符為默認修飾符,在同一個包下的任何類都可以訪問,
| 可見性修飾符 | 類內訪問 | 包內訪問 | 從不同包訪問 |
|---|---|---|---|
| public | 可以 | 可以 | 可以 |
| 默認 | 可以 | 可以 | 不可以 |
| private | 可以 | 不可以 | 不可以 |
8、可見性修飾符public和private分別表示可以從哪里訪問類成員?
可見性修飾符public表示可以從任何類中訪問,可見性修飾符private表示類成員只能從自身所在的類中訪問,
9、什么是資料域封裝?為什么要使用資料域封裝?
資料域封裝是對資料域使用private修飾符,將資料域宣告為私有域,使用資料域封裝的目的是避免從類的外部直接修改資料域的值,
10、在使用資料域之后,應如何讀取和修改資料域的值?
可以撰寫get方法獲取資料域的值,撰寫set方法修改資料域的值,
11、String型別的值是否可變?對String型別的值進行修改操作是否修改了String的內容?
由于String原始碼中,存盤字串內容的陣列使用關鍵字final修飾的,因此String型別的值不可變,對String型別的值進行修改沒有修改String的內容,而是創建了新的String物件,
補充:關于String型別的值不能修改的原因還有另外一種說法,因為我們知道final修飾的陣列的value內容有時候也是可以修改的,只是value不能指向其他的陣列物件,具體為什么不能修改,其實是因為String中存盤字串內容的陣列是private型別的,并且String類中并沒有對外提供修改內容的方法,所以字串物件才無法修改,
12、StringBuffer 和 StringBuilder 哪一種型別的效率更高?兩種型別分別適用于什么樣的場合?
StringBuilder 的效率更高,因為 StringBuffer對方法加了同步鎖,而 StringBuilder沒有對方法加同步鎖,雖然StringBuilder 的效率更高,但是因為沒有對方法加同步鎖,因此在多執行緒環境下不保證執行緒安全,只適合單執行緒環境,而 StringBuffer 可以用于多執行緒環境,
今日總結
今天和大家總結了在面向物件的考察點上一些常見的面試題,在這一篇中我們需要掌握初始化塊的呼叫順序、this關鍵字的使用、三種修飾符的作用范圍以及字串的三個常用操作類String、StringBuilder、StringBuffer,
面向物件的面試題比較多,之后還會繼續總結,如果小伙伴們有遇到其他相關的面試題,歡迎在評論區留言提出,我會把大家提出的總結到文章內, 歡迎小伙伴們一起評論區打卡學習!小伙伴們可也在左方加我好友一起探討學習!
我是灰小猿,我們下期見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/292020.html
標籤:java
