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

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

在 Random-TW 群組發布
大家好,今天繼續分析250+ Java開發者面試題。Java 開發者訪談問答分析。 第 4 - 1 部分分析的前幾部分:第一第二第三。那麼讓我們繼續吧。

29. 是否可以在構造函數中使用 return ?

可以,但return右側沒有回傳值。即可以使用return; 作為構造函數中計算時的輔助構造,以便緊急完成(中斷)後續程式碼的執行並完成物件的初始化。例如,我們有一個類Cat,如果Cat無家可歸 - isHomeless = true,我們需要完成初始化,而不填寫其他字段(畢竟,它們對我們來說是未知的,因為貓無家可歸):
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
但當涉及到特定值時,建構函數不能使用 return 來傳回值,因為:
  • 當聲明建構函式時,你不會有任何類似回傳類型的東西;
  • 通常,建構函數在實例化期間會隱式地呼叫;
  • 建構子不是方法:它是一種單獨的機制,其唯一目的是初始化實例變量,而new運算子負責建立物件。
Java 開發者訪談問答分析。 第 4 - 2 部分

30. 建構函數是否可以拋出異常?

建構函數處理異常的方式與方法完全相同。而如果方法允許我們透過在方法頭中寫入throws <ExceptionType>來拋出異常,那麼建構函式允許我們這樣做,並且在繼承和定義繼承建構子時,我們可以擴展異常類型。例如,IOException -> Exception(但反之則不然)。作為建構子拋出異常的範例,我們以Cat類別為例。假設在創建它時我們想從控制台輸入姓名和年齡:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
由於reader.readLine()拋出 IOException,我們在標頭中將其指定為可能拋出的例外。

31. 類別頭由哪些元素組成?寫一個例子

說到構成類別頭的元素,讓我們來看一個小圖:
  • 強制組件將放在括號 <> 中
  • 可選 - 在 {} 中
{類別存取修飾符}{類別靜態性}{類別終結性}{類別抽象} <類別名稱>{繼承父類別}{介面的實作} 因此,我們擁有: {class 存取修飾符} - 只有public修飾符和缺少的存取修飾符(即default )可用於 class 。 {class static} - static是修飾符,表示該類別是靜態的,僅適用於內部類別(其他類別內部的類別)。 {class Finality} - 如我們所記得的,這是final修飾符,在它的存在下,類別變得不可繼承(來自盒子的範例 - String)。 {class abstraction} - 修飾符-abstract,表示該類別可能有未實現的方法。此修飾符與final修飾符衝突,即類別頭中只能有其中之一,因為abstract修飾符意味著給定的類別將被繼承並且其抽象部分將實現。而final表示這是該類別的最終(final)版本,並且不能被繼承。實際上,同時使用這兩個修飾符是荒謬的,編譯器不會允許我們這樣做。 <class>是必要的關鍵字,指示類別聲明。 <class name>是一個簡單的類別名,它是特定Java類別的識別碼。完全限定類別名稱由完全限定包名 + 組成。+ 簡單的類別名稱。 {繼承自父類別} - 使用extends關鍵字指定父類別(如果有)。例如, ..擴充 ParentClass{interfaceimplementation} - 使用implements關鍵字指定此類實作的介面(如果有)。例如: ...實作 FirstInterface、SecondInterface ... 好吧,作為類別頭的範例,考慮Lion類別的頭,它繼承自Cat並實作WildAnimal介面:
public final class Lion extends Cat implements WildAnimal
Java 開發者訪談問答分析。 第 4 - 3 部分

32. 方法頭由哪些元素組成?寫一個例子

同樣,在查看構成方法頭的元素時,請考慮一個小圖表,其中:
  • 強制組件位於括號 <> 中
  • 可選 - 在 {} 中
{存取修飾符}{方法靜態}{方法抽象}{方法終結性}{同步修飾符} {本機修飾符}<傳回值><方法名稱> <(> {方法參數} <)>{拋出例外} {存取修飾符 } — 所有存取修飾符均可用於此方法:publicprotecteddefaultprivate{method static} - static是修飾符,表示該方法是靜態的,也就是說,它不是綁定到對象,而是綁定到類別。 {method Abstraction}abstract修飾符,表示方法沒有實作(主體)。為了正確操作,您還需要為提供該方法的類別提供一個抽象修飾符。如在類別頭中,這個修飾符與final修飾符衝突,但除此之外,它也與static修飾符衝突,因為 抽象方法意味著重寫後代中的方法,並且靜態方法不會被重寫。 {方法的最終性} -最終- 指示此方法不能被覆寫的修飾符。 {同步修飾符} -同步- 修飾符表示該方法受到保護,不會從不同執行緒同時存取它。如果該方法不是靜態的,它將關閉物件的 this 互斥體。如果該方法是靜態的,它將關閉目前類別的互斥鎖。 {native 修飾符} -本機- 此修飾符指示該方法是用不同的程式語言編寫的。 <return value>是方法應傳回的值的型別。如果它不應該傳回任何內容,則 void<方法名稱>是方法的名稱,它在系統中的識別符。 {方法參數}是方法採用的參數(參數):它們是實現其功能所必需的。 {可拋出異常} - throwsExceptionType - 此方法可以拋出的已檢查異常的清單。作為方法頭的範例,我將給出以下內容:
public static void main(String[] args) throws IOException

33. 如果基礎物件中沒有定義(但定義了另一個建構函數),則在後代物件中建立預設建構函數

我不完全理解這個問題本身,但也許這意味著,例如,在父級中我們有一些自訂建構函數:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
因此,在祖先類別中,我們肯定需要定義一個建構函數來填充(呼叫)父構造函數:
public  class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Java 開發者訪談問答分析。 第 4 - 4 部分

34.什麼時候使用this關鍵字?

在 Java 中,有兩種不同的意義。1. 作為當前物件的引用,例如this.age = 9。也就是說,this引用它被呼叫的物件以及使用this 的程式碼所引用的物件。主要作用是增加程式碼的可讀性,避免歧義。例如,如果內部類別欄位的名稱和方法參數相同:
public void setName(String name) {
   this.name = name;
}
也就是說,this.name是物件名稱的字段 ,是方法參數,靜態方法中不能使用this引用。2. this可以以方法呼叫的形式在建構函式中使用,例如this(value)。在這種情況下,它將呼叫同一類別的另一個建構函數。簡而言之,在創建物件時可以同時呼叫兩個建構函式:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
當建立Cat物件並呼叫第一個建構函式時,該物件的兩個欄位都會被呼叫並成功初始化。有一些細微差別:
  1. this()只在建構函數中起作用。
  2. 對另一個建構函式的參考必須位於建構函式區塊(主體)的第一行。因此,不能在一個建構函式中呼叫給定類別的多個(其他)建構函式。
Java 開發者訪談問答分析。 第 4 - 5 部分本文中有更多範例。

35.什麼是初始化器?

據我了解,在這個問題中我們討論的是普通和統計初始化塊。首先,讓我們記住什麼是初始化。初始化是創建、激活、工作準備、參數確定。使程式或元件進入準備使用狀態。正如您所記得的,在物件建立期間,可以在聲明時直接初始化類別變數:
class Cat {
   private int age = 9;
   private  String name = "Tom";
或透過構造函數在外部設定它:
class Cat {
   private int age;
   private  String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
但還有另一種方法:透過初始化區塊設定內部物件變量,它看起來像類別內部的 大括號{ } ,沒有名稱(如方法或建構函數):
class Cat {
   private int age;
   private  String name;

   {
       age = 10;
       name = "Tom";
   }
也就是說,初始化區塊是創建物件時載入的一段程式碼。通常,此類區塊用於執行載入類別時所需的一些複雜計算。這些計算的結果可以指定為變數的值。另外,除了常規初始化區塊之外,還有靜態初始化區塊,它們看起來相同,但在大括號之前有static關鍵字:
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
該塊與前一個塊完全相同。但是,如果常規物件在每個物件初始化時觸發,則靜態物件只會在類別載入時觸發一次。在這樣的區塊中,通常也會為後續靜態類別變數的初始化進行一些複雜的計算。與靜態方法相同的限制也適用於靜態區塊:它不能使用非靜態數據,也不能使用對當前物件的引用 - thisJava 開發者訪談問答分析。 第 4 - 6 部分接下來,我們可以看到類別的初始化順序(及其祖先),以便更好地理解初始化塊被觸發的時刻。

36.繼承一個類別public class Child extends Parent,寫出該物件的初始化順序

當Child類別被載入時,初始化順序如下:
  1. 類別的靜態欄位。
  2. 類別的靜態初始化塊。
  3. Сhild類別的靜態字段。
  4. Child類別的靜態初始化區塊。
  5. Parent類別的非靜態欄位。
  6. 不是父類別的靜態初始化塊。
  7. 類別的建構子。
  8. Child類別的非靜態欄位。
  9. 不是Child類別的靜態初始化區塊。
  10. Child類別的建構子。
Java 開發者訪談問答分析。 第 4 - 7 部分這是一篇簡短的文章,解釋了實務上的初始化順序。

37.你知道類別(物件)之間有哪些關係?

Java中類別之間的關係有兩種:
  • IS-A關係
OOP 中的 IS-A 原則是基於類別繼承或介面實作。例如,如果類別Lion繼承自Cat,我們就說LionCat
Lion IS-A Cat
(但不是每隻貓都是獅子)介面的情況完全相同。如果Lion類別實作了WildAnimal接口,那麼它們也存在關係:
Lion IS-A WildAnimal
  • HAS-A關係
這種類型的關係是基於其他類別對類別的使用,也稱為「關聯」。關聯是一個類別引用另一個類別(甚至相互引用)。例如,Car類可以引用Passenger類,關係如下:
Car HAS-A Passenger
反之亦然:如果Passenger引用了Car,那麼關係如下:
Passenger HAS-A Car

38.你知道物體之間有哪些關聯關係?

聚合和組合只不過是關聯的特殊情況。 聚合是一種關係,其中一個物件是另一個物件的一部分。例如,乘客可能在車上。此外,可能有幾位乘客,也可能完全沒有(如果我們談論的是特斯拉,則不需要司機)。例如:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
也就是說,我們不關心乘客的數量(或是否有乘客):Car類的功能不依賴於此。聚合也意味著當一個物件被另一個物件使用時,第一個物件可以在其他物件中使用。例如,同一個學生可以既是針織俱樂部的成員,也是搖滾音樂團體的成員,同時又加入了英語學習者團體。如您所知,聚合是類別之間較鬆散的關聯關係。當一個物件不僅是另一個物件的一部分,而且另一個物件的工作非常依賴第一個物件時,組合是一種更嚴格的關係Java 開發者訪談問答分析。 第 4 - 8 部分例如,汽車引擎。儘管引擎可以脫離汽車而存在,但離開汽車就毫無用處。好吧,汽車沒有引擎就無法運作:
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
組合也意味著當一個物件被另一個物件使用時,第一個物件不能屬於任何其他物件。如果我們回到我們的例子,一台引擎只能屬於一輛汽車,但不能同時屬於兩輛或更多汽車。今天我們可能就停在這裡。Java 開發者訪談問答分析。 第 4 - 9 部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION