CodeGym /Java Blog /Toto sisi /探索 Java 開發人員職位面試中的問題和答案。第五部分
John Squirrels
等級 41
San Francisco

探索 Java 開發人員職位面試中的問題和答案。第五部分

在 Toto sisi 群組發布
你好你好!如今,Java 開發人員的需求量很大。當然,我不能為你提供職缺,但我會盡力幫助你獲得一些新知識並填補一些空白。那麼讓我們繼續回顧一下 Java 開發人員面試問題。您可以在文章末尾找到評論前面部分的連結。 探索 Java 開發人員職位面試中的問題和答案。 第 5 - 1 部分

39. Java中的存取修飾符有哪些?說出他們的名字。它們有什麼用?

我之前在一個有關用於實作封裝的 Java 元素的問題中介紹了存取修飾符。但我還是要提醒你。Java 中的存取修飾符是描述授予特定 Java 元件的存取等級的關鍵字。存在以下存取修飾符:
  • public — 用此修飾符標記的元素是公共的。換句話說,欄位和方法以及使用 public 修飾符聲明的類別對於其自己的套件和外部包中的其他類別都是可見的;
  • protected — 標有此修飾符的元素可以從目前套件或衍生類別中其自己的類別中的任何位置訪問,即使它們位於其他套件中;
  • 當未指示存取修飾符時,預設(或根本沒有修飾符)隱式應用。它與前一個類似,只是它在其他套件中找到的衍生類別中可見;
  • private-這是所有修飾符中最私密的。它只允許存取當前類別中的元素。

40.說出靜態和非靜態方法的主要特徵

主要差異在於靜態方法屬於類別。事實上,您不需要建立此類別的實例 - 可以僅從類別類型呼叫靜態方法。例如,假設我們有一個撫摸貓的靜態方法:
public class CatService {
   public static void petTheCat(Cat cat) {
       System.out.println("Pet the cat: " + cat.getName());
   }
我們不需要CatService類別的實例來呼叫它:
Cat cat = new Cat(7, "Bobby");
CatService.petTheCat(cat);
相較之下,普通方法綁定(屬於)一個物件。要呼叫它們,您必須有一個將在其上呼叫該方法的實例(物件)。例如,假設我們的貓有一個非靜態方法meow()
class Cat {
   public void meow() {
       System.out.println("Meow! Meow! Meow!");
   }
要呼叫此方法,我們需要一個特定的貓實例:
Cat cat = new Cat(7, "Bobby");
cat.meow();

41. 適用於靜態和非靜態方法的主要限制是什麼?

正如我之前所說,普通(非靜態)方法的主要限制是必須始終存在呼叫該方法的實例。但靜態方法不需要這個。此外,靜態方法不能使用物件元素的 this引用,因為現在該方法存在當前物件。

42. static關鍵字是什麼意思?靜態方法可以被重寫或重載嗎?

用static關鍵字標記的元素不屬於類別的實例,而是屬於類別本身。它是在類別本身載入時載入的。靜態元素對於整個程式是相同的,而非靜態元素僅對於特定物件是相同的。以下元素可以是靜態的:
  • 類別的字段;
  • 類別的初始化塊;
  • 類別的方法;
  • 一個類別的巢狀類別(當然,這也是同義反覆)。
靜態方法不能被重寫:它屬於類別並且不被繼承,但同時它可以被重載。

43. 一個方法可以同時是靜態的、抽象的嗎?

我已經在上一篇文章中回答過這個問題:方法不能同時是抽象的和靜態的。如果一個方法是抽象的,則意味著必須在子類別中重寫它。但是靜態方法屬於類,且不能被覆寫。這會產生矛盾,編譯器會注意到這一點並對此感到不安。如果您發現自己處於這種情況,您應該認真考慮應用程式架構的正確性(提示:它顯然有問題)。 探索 Java 開發人員職位面試中的問題和答案。 第 5 - 2 部分

44. 靜態方法可以用在非靜態方法中間嗎?反之亦然?為什麼?

我們可以在非靜態方法中使用靜態方法。沒有什麼可以阻止這一點。也就是說,相反的情況是不可能的:靜態方法不能在不引用類別的特定實例的情況下使用非靜態方法。請記住,類別的靜態成員無權存取this引用:您可以擁有任意多個類別的具體對象,並且每個物件都將包含一個this引用,這是一個自引用。那麼如何確定使用哪個this引用呢?呃,你不知道。這就是為什麼靜態元素不能在沒有引用特定物件的情況下引用非靜態元素。基本上,靜態方法只有在引用特定物件時才可以使用非靜態方法。例如,作為方法參數出現的一個:
public static void petTheCat(Cat cat) {
   System.out.println("Pet the cat: " + cat.getName());
}
這裡我們看到,在靜態petTheCat()方法中呼叫getName ,這是Cat物件普通的非靜態方法。

45.什麼是介面?能有最終的介面嗎?

我們還記得 Java 沒有多重繼承。接口是它的一種替代方案。介面就像一個非常精簡的類別。他們定義了功能,但沒有具體的實現。該任務留給實作這些介面的類別。接口範例:
public interface Animal {
    void speak();
}
類別的介面實作範例
class Cat implements Animal {

   @Override
   public void speak() {
       System.out.println("Meow! Meow! Meow!");
   }
}
以下是有關使用介面需要了解的重要事項:
  1. 介面方法必須僅包含標頭。它們不能有特定的方法體,即它們必須是抽象的(儘管它們不使用abstract關鍵字)。但也有例外:靜態方法和預設方法,它們需要方法體。

  2. 一個類別可以實作許多介面(正如我所說,介面是多重繼承的替代方案)。介面名稱在方法頭中以逗號分隔:類別 Lion 實作 Animal, Wild

  3. 介面是使用interface關鍵字建立的。

  4. 當類別實作介面時,我們使用implements關鍵字。

  5. 實作某個介面的類別必須實作其所有抽象方法,或者必須將自身宣告為抽象。

  6. 使用介面的主要目的是實現多態性(使物件能夠呈現多種形式)。

  7. 通常,方法的存取修飾符不在介面中指示:預設情況下它們是public 的,並且您不能指定public之外的修飾符。從 Java 9 開始,您可以在方法上使用private修飾符。

  8. 預設情況下,介面變數是static final。換句話說,它們是常數——它們必須始終直接在介面中初始化。

  9. 您無法建立介面的實例。

介面是否可以是final的問題的答案當然是否定的。事實上,擁有介面的全部意義在於實現它們。我們都記得很清楚,類別層級的Final修飾符使得類別不可繼承,對於介面來說 - 不可實現。為什麼我們需要一個我們無法實現和使用的介面?你是對的——我們不會!編譯器也同意。:) 探索 Java 開發人員職位面試中的問題和答案。 第 5 - 3 部分實際上,從 Java 8 開始引入靜態介面方法,這可能是有道理的,但這並不能改變介面不能是 Final 的事實。我只是非常膚淺地談論了接口,因為這是一個廣泛的話題。有關這方面的更多信息,請參閱有關 Java 中的介面 以及抽象類別和介面之間的區別 的文章。

46. 靜態字段可以在哪裡初始化?

靜態字段可以初始化:
  • 聲明後立即使用等號 ( = );
  • 在靜態初始化塊中;
  • 在非靜態初始化區塊中(但你需要明白,每次建立物件時,執行此初始化區塊時靜態欄位都會被覆寫;
  • 在類別構造函數中。每次呼叫建構函式時(即每次使用此建構函式建立物件時),該欄位都會被覆寫;
  • 在靜態方法中;
  • 在非靜態方法中;
  • 在巢狀的靜態和非靜態、本地和匿名類別中。

47.什麼是匿名類別?

匿名類別是沒有自己的類型的類別。我在說什麼?當我們談論介面時,我提到您無法建立物件的實例:您只能建立實作介面的類別的實例。如果您不希望某個類別實作介面但需要一個實作該介面的物件怎麼辦?這可能是該物體的唯一用途。而且您無需創建成熟的實作類別。你會怎麼做?這是正確的!透過使用匿名類別! 探索 Java 開發人員職位面試中的問題和答案。 第 5 - 4 部分假設我們有一些Animal介面:
public final interface Animal {
   public void speak();
}
如果我們想使用匿名類別來實例化給定的介面:
Animal cat = new Animal() {
   @Override
   public void speak() {
       System.out.println("Meow! Meow! Meow!");
   }
};
然後,您可以安全地使用該物件及其實作的talk()方法。換句話說,匿名類別此時此地實作了介面及其所有抽象方法。否則,我們將無法建立介面/抽象類別對象,因為會有未實現/抽象方法。正如我所提到的,匿名類別不僅用於實作介面的抽象方法,也用於實作抽象類別的抽象方法。這種方法適用於物件被使用一次或給定方法實現僅需要一次的情況。無需建立一個單獨的類別來實作所需的抽象類別/介面。但我也注意到,匿名類別在工作中很少使用。原則上,普通班仍優先考慮。您可以在本文中 閱讀有關匿名類別的更多資訊。

48.什麼是原始類別?

我認為這是一個誤導性的問題,可能是一個欺騙性的問題,因為 Java 沒有原始類別這樣的東西。只有我們之前考慮過的原始類型的概念。我們記得 Java 有 8 種基本型別:byteShortintlongfloatdoublecharboolean

49.什麼是包裝類?

在 Java 中使用基本類型的主要問題是它們不是類,而 Java 是一種 OOP 語言。也就是說,用這種語言寫的程式相當於物件之間的互動。但基元不是對象。它們沒有方法,甚至沒有Object類別的標準方法。但是如果我們需要使用原語作為Map中的鍵呢?然後我們需要呼叫它的hashCode()方法。您也可以在那裡呼叫它的equals()方法。然後怎樣呢?在很多時候你需要一個類,而不是一個基元。這使得原語在程序中變得不可用和不受歡迎的元素,因為它們違反了 OOP 的理念。但情況並不像看起來那麼糟。畢竟,Java 有原始包裝器的概念。在 Java 中,每個基本型別都有一個雙胞胎-包裝類別。
  • 位元組->位元組.class
  • ->短類
  • int ->整數類
  • ->長類
  • 浮動-> Float.class
  • ->雙.class
  • 字元->字元.class
  • 布林值-> Boolean.class
這些類型代表簡單類型,但在成熟的類別中具有許多不同且有用的方法。引入自動裝箱和拆箱的概念是為了方便使用這些類別。 自動裝箱是在必要時將基本類型自動轉換為其類似類別(例如,將int轉換為Integer)。 拆箱是相反的過程:將原始包裝類別自動轉換為原始類型(例如,將Integer轉換為int)。由於引入了原始包裝類別以及自動裝箱拆箱過程,原始類型現在已成為 Java 作為 OOP 語言的成熟成員。 探索 Java 開發人員職位面試中的問題和答案。 第 5 - 5 部分為了更深入地討論這個主題,我強烈建議閱讀這篇文章

50.什麼是嵌套類別?它用在哪裡?

嵌套類別是一個本身是另一個類別的成員的類別。Java 中的巢狀類別有 4 種: 1. 內部類別 這種類別直接在另一個類別的主體中宣告。內部類別是非靜態巢狀類,可以存取外部類別的任何私人欄位或實例方法。作為範例,讓我們創建一個包含動物(斑馬)的動物園:
public class Zoo {
   class Zebra {
       public void eat(String food) {
           System.out.println("Zebra eats " + food);
       }
   }
}
並不複雜,對吧?我們來看一個建立內部類別實例的範例:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.eat("apple");
正如您已經看到的,首先需要建立封閉類別的物件。然後使用物件引用建立內部類別的實例。我還想指出,內部類別(非靜態巢狀類別)不能有靜態方法或靜態欄位。這正是因為內部類別與其外部類別的實例隱式關聯,因此不能在其內部聲明任何靜態方法。 2. 靜態巢狀類別 這些類別與前面的類別類似,但它們在類別宣告中具有static存取修飾符。由於這種類別無法存取外部類別的非靜態字段,因此它看起來更像是外部類別的靜態部分而不是內部類別。但是這個類別可以存取外部類別的所有靜態成員,甚至是私人成員。靜態巢狀類別的範例:
public class Zoo {
   static class Zebra {
       public void eat(String food) {
           System.out.println("Zebra eats " + food);
       }
   }
}
它的創建方式與之前的略有不同:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.eat("apple");
這裡我們不需要外部類別的物件來建立靜態巢狀類別的物件。我們只需要知道嵌套類別的名稱就可以在外部類別中找到它。 3. 局部類別 局部類別是在方法體中宣告的類別。本地類別的物件只能在封閉方法中建立和使用。例子:
public class Zoo {
   public void feed(String animal, String food) {
       switch(animal) {
           case "zebra":
               class Zebra {
                   public void eat(String food) {
                       System.out.println("Zebra eats " + food);
                   }
               }
               Zebra zebra = new Zebra();
               zebra.eat(food);
               ...
這是一個例子:
Zoo zoo = new Zoo();
zoo.feed("zebra", "apple");
如果您沒有看到feed()方法 的程式碼,那麼您甚至不會懷疑本地類別的存在,不是嗎?本地類別不能是static瞬態的,但可以將其標記為抽像最終(其中之一或另一個,但不能同時使用這兩個修飾符,因為同時使用這兩個修飾符會產生衝突)。 4. 匿名類別 上面我們已經討論過匿名類,您會記得,它們可以從兩個來源建立:介面和類別。 使用它們的原因 使用 嵌套靜態和非靜態類別是因為有時最好將小類別嵌入到更通用的類別中並將它們保持在一起,以便它們具有更高的內聚性和共同的目的。基本上,嵌套類別可以讓您增加程式碼的封裝性。如果本機類別僅在單一方法中使用,您可以選擇使用該類別。在這種情況下,我們是否需要將程式碼分散到應用程式中?不。話雖如此,我要補充一點,根據我的經驗,我從未見過有人使用本地類,因為是否需要它們存在很大爭議。當僅需要一次介面或抽象類別的特定實作時,您可以使用匿名類別。在這種情況下,無需建立具有實現的單獨的、成熟的類別。相反,我們保持簡單並使用匿名類別實現了我們需要的方法,使用了該對象,然後忘記了它(當然,垃圾收集器沒有忘記)。本文將增強您對嵌套類別的理解。

51.類別可以有哪些存取修飾符?

類別有不同類型,並且適用不同的存取修飾符:
  • 外部類別可以具有public存取修飾符或根本沒有修飾符(預設修飾符);
  • 內部類別(非靜態巢狀類別)可以具有 4 個存取修飾符中的任何一個;
  • 嵌套靜態類別可以具有protected以外的任何一個存取修飾符,因為該修飾符意味著繼承,這與該類別的任何靜態成員相矛盾(靜態成員不被繼承);
  • 局部類別只能有預設修飾符(即根本沒有修飾符);
  • 匿名類別沒有類別聲明,因此它根本沒有存取修飾符。
今天我們就到這裡結束。再見!探索 Java 開發人員職位面試中的問題和答案。 第 5 - 6 部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION