JavaRush /Java Blog /Random-TW /Java 開發者訪談問答分析。第五部分

Java 開發者訪談問答分析。第五部分

在 Random-TW 群組發布
你好你好!如今,Java 開發人員的需求量很大。當然,我不能為你提供一個空缺,但我會盡力幫助你獲得新知識並彌補一些差距。因此,我們繼續分析250 多個Java 開發人員面試問題。分析前面部分的連結位於文章末尾。Java 開發者訪談問答分析。 第 5 - 1 部分

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

我之前在有關 Java 封裝元素的問題中描述了存取修飾符。但無論如何我都會提醒你。Java 中的存取修飾符是描述授予特定 Java 元件的存取等級的關鍵字。存取修飾符可以是:
  • public - 具有此修飾符的元素將可公開存取。那些。使用 public 修飾符宣告的欄位和方法、類別對於目前套件和外部套件中的其他類別都是可見的;
  • protected - 具有此修飾符的元素可以從當前包的當前類別或後代類別中的任何位置訪問,即使它們位於其他包中;
  • default或缺少修飾符 - 當根本未指定存取修飾符時,隱式使用此修飾符。它與前一個類似,不同之處在於其他包中的後代類別允許可見性;
  • private是所有修飾符中最私有的,僅允許存取目前類別中的元素。
Java 開發者訪談問答分析。 第 5 - 2 部分

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

一個非常奇怪的提法—「可變方法」。當然,這是指普通的非靜態方法。因此,主要區別在於靜態方法屬於類,事實上,對於它們,您不需要建立此類的實例:只能使用類別類型來呼叫它。例如,我們有一個靜態方法來撫摸貓:
public class CatService {
   public static void petTheCat(Cat cat) {
       System.out.println("Погладить кота - " + cat.getName());
   }
我們不需要CatService 類別的實例來呼叫它:
Cat cat = new Cat(7, "Bobi");
CatService.petTheCat(cat);
雖然普通方法綁定(屬於)一個對象,並且為了呼叫它們,您必須有一個將在其上呼叫該方法的實例(對象)。例如,貓有一個非靜態方法 - meowing:
class Cat {
   public void mew() {
       System.out.println("Meow! Meow! Meow!");
   }
要呼叫此方法,我們需要貓的特定實例:
Cat cat = new Cat(7, "Bobi");
cat.mew();

41. 靜態和「變數」方法的主要限制是什麼?

正如我之前所說,常規方法的主要限制是必須始終存在某個實例來呼叫該方法。但是靜態方法不需要 this,但它不能引用this引用(指向當前物件的元素),因為當前物件不存在。

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

static關鍵字指定的元素不屬於類別的對象,而是屬於類,並且在載入類別本身時載入。靜態元素是整個程式的唯一元素,而常規元素是特定物件的唯一元素。靜態可以是:
  • 類別字段;
  • 類別初始化塊;
  • 類別方法;
  • 類別的內部類別(但是,這仍然是同義反覆)。
靜態方法不能被覆寫:它屬於類別並且不被繼承,但同時它可以被重載。

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

我在上一篇文章中已經提過:方法不能同時是抽象的、靜態的。方法的抽象性意味著它必須在後繼者中被重寫。同時,靜態方法屬於類別並且不能被重寫:這會導致矛盾,編譯器會看到並開始咒罵。如果你有這樣的情況,你應該認真思考你的應用程式架構的正確性(畢竟,它顯然有問題)。Java 開發者訪談問答分析。 第 5 - 3 部分

44. 是否可以在常規方法中使用靜態方法?反之亦然?為什麼?

靜態方法可以在常規方法中使用,因為沒有什麼可以阻止這一點。同時,相反的情況是不可能的:靜態方法不能在沒有對該類別的特定實例的引用的情況下使用常規方法。正如我們所記得的,this引用不適用於靜態類別成員:可以有任意多個類別的特定對象,並且每個對象內部都會有一個對其自身的引用 - this。那麼您如何理解您需要選擇哪個特定的連結呢?但沒辦法。因此,靜態元素不能引用非靜態元素,除非引用特定物件。實際上,靜態方法只有在引用特定物件時才可以使用非靜態方法。例如,作為參數出現的一個:
public static void petTheCat(Cat cat) {
   System.out.println("Погладить кота - " + cat.getName());
}
這裡我們看到靜態方法petTheCat呼叫Cat物件的普通非靜態方法- getName

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

我們記得,Java 中沒有多重繼承。接口是它的一種替代方案。該介面看起來像是一個非常精簡的類別。它們定義功能時沒有具體的實現,而是由實現(實現)這些介面的類別來實現。介面範例:
public interface Animal {
    void voice();
}
類別實作介面的範例:
class Cat implements Animal {

   @Override
   public void voice() {
       System.out.println("Meow! Meow! Meow!");
   }
}
關於使用接口,您需要了解的主要內容是:
  1. 介面方法應該只包含一個標頭,沒有特定的方法體,即 必須是抽象的(但不使用abstract關鍵字)。靜態方法和預設方法除外,它們需要方法體。
  2. 一個類別可以實作許多介面(正如我所說,這是多重繼承的替代方案),這些介面以逗號分隔:class Lion Implements Animal, Wild
  3. 介面是使用關鍵字-interface建立的。
  4. 當透過類別實作介面時,關鍵字是implements
  5. 實作特定介面的類別必須實作其所有抽象方法,或者必須將自身聲明為抽象。
  6. 使用介面的主要目的是實現多態性(物件採取多種形式的能力)。
  7. 一般來說,方法的存取修飾符不會寫在介面中:它們預設是public 的,並且不能指定public以外的其他修飾符。從 Java 9 開始,您可以對方法使用private修飾符。
  8. 介面變數預設是 static final,換句話說,是常數:它們總是需要直接在介面中初始化。
  9. 您無法建立介面物件。
接口是否可以是final的這個問題的答案當然是不能。畢竟,介面的本質就是要實現。我們都記得很清楚,類別層級的Final使其不可繼承,而對於介面而言,則使其不可實現。為什麼我們需要一個無法實現和使用的介面?沒錯——沒必要!編譯器是這麼認為的))Java 開發者訪談問答分析。 第 5 - 4 部分這個意義只是在Java 8的介面中引入靜態方法時才出現的,但這並沒有改變介面不能是final的事實。我非常膚淺地談論了接口,因為... 這是一個廣泛的話題。請閱讀有關Java 中的介面以及抽象類別和介面之間的差異的文章,以了解更多相關內容。

46. 哪裡可以初始化靜態欄位?

靜態字段可以初始化:
  • 直接在聲明時透過等號=
  • 在靜態初始化塊中;
  • 在非靜態初始化區塊中,但是你必須明白,每次建立物件時,該欄位都會被這個初始化區塊覆蓋;
  • 在類別構造函數中。每次呼叫該建構函式時(即透過該建構函式建立物件時),該欄位都會被覆寫;
  • 在靜態方法中;
  • 在非靜態方法中;
  • 在內部靜態和非靜態、本地和匿名類別中。

47.什麼是匿名類別?

匿名類別是沒有自己的類型的類別。我在說什麼?當我們談論介面時,我提到您不能建立介面物件:您只能建立實現該介面的類別的物件。如果不想在類別中實作接口,但仍需要接口類型的物件怎麼辦?最有可能的是,這將是使用該物件的單一情況。而且您不需要創建成熟的實作類別。你將如何做到這一點?正確的!通過匿名課程!Java 開發者訪談問答分析。 第 5 - 5 部分假設我們有一些Animal介面:
public final interface Animal {
   public void voice();
}
如果我們想透過匿名類別實例化這個介面:
Animal cat = new Animal() {
   @Override
   public void voice() {
       System.out.println("Meow! Meow! Meow!");
   }
};
然後您就可以安全地使用這個物件及其實現的方法—​​語音。也就是說,匿名類別此時此地實作該介面及其所有抽象方法。否則,我們將無法建立介面/抽象類別對象,因為存在未實現/抽象方法。正如我所提到的,匿名類別不僅用於實作介面的抽象方法,也用於實作抽象類別的抽象方法。這種方法適用於一次性使用物件或只需要一次給定方法實現的情況,並且不需要創建一個單獨的類別來實現所需的抽象類別/介面。但我還要指出,在工作中很少使用匿名類別:通常,仍然優先考慮普通類別。您可以在本文中閱讀有關匿名類別的更多資訊。

48.什麼是原始類別?

對我來說,這是一個非常奇怪的問題,也許這是一個陷阱問題,因為在 Java 中不存在原始類別這樣的東西:除了我們之前已經考慮過的原始類型的概念。我們記得,Java 中有 8 種基本型別:byteshortintlongfloatdoublecharbooleanJava 開發者訪談問答分析。 第 5 - 6 部分

49.什麼是「包裝」類?

在 Java 中使用基本類型的主要問題是它們仍然不是類,並且 Java 仍然是一種 OOP 語言。也就是說,用這種語言編寫的程式被簡化為物件之間的互動。嗯,基元不是對象。它們沒有方法,甚至沒有Object類別中的標準方法。那麼,如果我們需要使用原語作為Map中的鍵呢?然後需要呼叫hashCode方法。您也可以在那裡呼叫equals方法。然後怎樣呢?在很多時候,應該有一個類,而不是一個原語,這使得原語在程序中成為未使用的和不需要的元素,因為這破壞了 OOP 的思想。但並非一切都像看起來那麼糟。畢竟,Java 有原始包裝器的概念。每個原始類型都有一個模擬類別:
  • 位元組->位元組.class
  • ->短類
  • int ->整數類
  • ->長類
  • 浮動-> Float.class
  • ->雙.class
  • 字元->字元.class
  • 布林值-> Boolean.class
這是簡單類型的表示,但以成熟的類別的形式存在,具有一堆不同的函數方法。為了方便使用這些類,引入了自動裝箱和拆箱的概念。 自動裝箱- 必要時將原始類型自動轉換為類比類別(例如,intInteger)。 拆箱是前一個過程的逆過程:自動將原始包裝類別轉換為原始型別(例如,將Integer轉換為int)。由於引入了原始包裝類別以及自動裝箱拆箱過程,原始類型能夠成為 OOP 語言 - Java 的成熟成員。Java 開發者訪談問答分析。 第 5 - 7 部分要了解有關此主題的更多信息,我強烈建議閱讀這篇文章

50.什麼是嵌套類別?什麼時候使用?

嵌套類別是一個內部類,它是另一個類別的成員。在Java中,此類內部類別有4種類型: 1. 內部類別 這種類型的類別直接在另一個類別的主體中聲明。嵌套內部類別可以存取外部類別實例的任何私有欄位或方法。例如,讓我們創建一個動物園,其中有一種動物 - 斑馬:
public class Zoo {
   class Zebra {
       public void toFeed(String food) {
           System.out.println("Дать зебре - " + food);
       }
   }
}
沒什麼複雜的,對吧?我們來看一個創建內部類別物件的範例:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.toFeed("яблоко");
正如您已經看到的,必須建立框架類別的對象,基於該對象的參考您可以建立內部類別的對象。我還想指出,巢狀內部類別不能有靜態方法或靜態欄位。這是因為內部類別與其外部類別的物件隱式關聯,內部類別不能在其內部聲明任何靜態方法。 2. 靜態巢狀類別 該類別與前一個類別類似,只是它在類別聲明附近有一個static存取修飾符。由於這種類別無法存取外部類別的非靜態字段,因此它更像是外部類別的靜態部分而不是內部類別。在這種情況下,類別資料可以存取外部類別的所有靜態成員,甚至是私人成員。靜態巢狀類別的範例:
public class Zoo {
   static class Zebra {
       public void toFeed(String food) {
           System.out.println("Дать зебре - " + food);
       }
   }
}
建立方法與之前略有不同:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.toFeed("яблоко");
這裡我們不需要外部類別的物件來建立嵌套靜態類別的物件。從外部類別中,我們只需要它的類型,這樣我們就可以找到嵌套類別的位置。 3. 局部類 局部類別是在方法體內聲明的類,並且只能在該方法內建立和使用局部類別的物件。例子:
public class Zoo {
   public void toFeed(String animal, String food) {
       switch(animal){
           case "зебра":
               class Zebra {
                   void toFeedZebra(String food) {
                       System.out.println("Дать зебре - " + food);
                   }
               }
               Zebra zebra = new Zebra();
               zebra.toFeedZebra(food);
               ...
使用範例:
Zoo zoo = new Zoo();
zoo.toFeed("зебра", "яблоко");
如果沒有看到toFeed方法 的程式碼,您甚至不會懷疑本地類別的存在,不是嗎?局部類別不能是static瞬態,但可以標記為abstractfinal(只能是OR,因為使用這兩個修飾符會導致衝突)。 4. 匿名類別 我們已經在上面討論了匿名類,正如您所記得的,它們可以從兩個來源創建:介面和類別。 使用內部靜態和非靜態類別的原因 是因為有時最好將小類別嵌入到較大的類別中並將它們保持在一起:這樣它們將具有更高的內聚性和共同的目的。實際上,嵌套類別的使用增加了程式碼封裝性。選擇局部類別的原因可能是給定的類別僅在單一方法中使用。在這種情況下,是否有必要將程式碼分散到整個應用程式中?不。但同時我要補充一點,在我的實踐中我從未見過本地類的使用,因為 對它們的需求存在很大爭議。嗯,使用匿名類別的原因可能是介面或抽象類別的特定實作只需要一次,因此不需要創建一個單獨的、成熟的類別及其實作。相反,我們以一種簡單的方式,透過一個匿名類別實現了我們需要的方法,使用了這個對象,然後忘記了它(好吧,垃圾收集器記住了它)。這篇文章和這篇Java 開發者訪談問答分析。 第 5 - 8 部分文章將幫助您更詳細地研究內部類別。

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

我們記得,有不同類型的類,並且適用於它們的存取修飾符也不同:
  • 外部類別可以有存取修飾符public或沒有修飾符(預設修飾符);
  • 內部類別支援所有 4 個存取修飾符;
  • 巢狀靜態類別支援除protected之外的所有存取修飾符,因為 這個修飾符暗示著繼承,這與類別的靜態成員相矛盾(靜態元素不被繼承);
  • 本機類別只能有預設修飾符(即根本沒有修飾符);
  • 匿名類別:如果沒有類別類型聲明,則根本沒有存取修飾符。
這就是我們今天要停下來的地方。再見!Java 開發者訪談問答分析。 第 5 - 9 部分
該系列其他材料:
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION