JavaRush /Java Blog /Random-TW /Java 中的 Instanceof 運算符

Java 中的 Instanceof 運算符

在 Random-TW 群組發布
你好!今天我們將討論instanceof運算符,看一下它的使用範例,並討論一些與其操作相關的要點:) 在JavaRush的早期階段,您已經遇到過這個運算符。你還記得為什麼需要它嗎?如果沒有,也沒關係,我們一起記得。需要使用instanceof運算子來檢查變數X引用的物件是否是從某個類別Y創建的。聽起來很簡單。為什麼我們又回到這個話題?首先,因為現在你已經熟悉了Java中的繼承機制和其他OOP原理。instanceof的主題將會更加清晰,我們將研究更進階的用例。去!您可能還記得,如果測試為真,則Instanceof 運算子如何運作 - 1instanceof 運算子傳回true ;如果結果為false ,則傳回 false。因此,它最常見於各種類型的測試條件 ( if…else)。讓我們從更簡單的例子開始:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
你認為控制台會輸出什麼?嗯,這很明顯:) 該物件х是一個 Integer,所以結果將為true。控制台輸出:true 讓我們嘗試檢查它是否屬於字串:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String);// error!
   }
}
我們收到一個錯誤。請注意:編譯器甚至在程式碼執行之前就發出了它!他立刻看到Integer和String不能自動互相轉換,也不具有繼承關係。因此,不會從 String 建立 Integer 類別物件。這很方便,有助於避免在程式執行期間​​出現奇怪的錯誤,因此編譯器在這裡幫助了我們:) 現在讓我們嘗試看看更複雜的範例。既然我們提到了繼承,那麼讓我們使用這個小型類別系統:
public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
我們已經知道正常情況下檢查一個物件是否屬於某個類別時instanceof的行為如何,但是如果我們在這裡添加父子關係會發生什麼? Instanceof 運算子如何運作 - 2 例如,您認為以下檢查會產生什麼結果:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
輸出:true false 需要回答的主要問題是,instanceof 究竟如何破解「基於類別創建的物件」的概念?結果,我們得到了它Сat instanceof Animal == true,但人們可能會對這樣的表達提出錯誤。為什麼這個物件是Cat基於類別創建的Animal?不是只是根據自己的類別創建的嗎?答案很簡單,您可能已經想到了。記住創建物件時呼叫建構函數和初始化變數的順序。我們已經在有關類別構造函數的文章中討論了這個主題。這是該講座中的一個例子:
public class Animal {

   String brain = "The initial value of brain in the Animal class";
   String heart = "The initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("The constructor of the Animal base class is being executed");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("The current value of the static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in class Animal = " + this.brain);
       System.out.println("Current value of heart in class Animal = " + this.heart);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor completed!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

class Cat extends Animal {

   String tail = "The initial value of tail in the Cat class";

   static int catsCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The constructor of the Cat class has started (the Animal constructor has already been executed)");
       System.out.println("The current value of the static variable catsCount = " + catsCount);
       System.out.println("Current value tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
如果你在 IDE 中運行它,控制台輸出將如下所示: The constructor of the base class Animal is running. Have the Variables of the Animal class have beeninitialized? 靜態變數animalCount的目前值 = 7700000 Animal類別中brain的目前值 = Animal類別中brain的初始值 Animal類別中heart的目前值 = Animal類別中heart的初始值 Animal類別基底類別的建構子已經完成了它的工作!Brain 的目前值 = Brain Heart 的目前值 = Heart Cat 類別的建構子已經開始工作(Animal 建構函式已經執行完畢) 靜態變數 catsCount 的目前值 = 37 tail 的目前值 = 中 tail 的初始值Cat 類別tail 目前值= Tail 現在你還記得嗎?:) 建立任何物件時,請務必先呼叫基底類別建構函式(如果有)。Instanceof 在嘗試確定物件是否是А從類別建立時遵循此原則Б。如果基底類別的建構子被調用,那麼就沒有疑問了。透過第二次檢查,一切都變得更簡單:
System.out.println(cat instanceof MaineCoon);
MaineCoon創建時沒有呼叫 建構函數Cat,這是合乎邏輯的。畢竟,MaineCoon他是後人Cat,不是祖先。但Cat它不是一個模板。好吧,這看起來很清楚。如果我們這樣做會發生什麼:
public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
嗯...這更複雜。讓我們試著推理一下。我們有一個類型的變量Cat,並且為它分配了一個類型的物件MaineCoon。順便問一下,為什麼這會起作用?是否有可能做到這一點?能。畢竟,任何緬因貓都是貓。如果還不完全清楚,請記住原始類型擴充的範例:
public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
數字1024:它很容易適合long變量,因為位元組數足夠了(還記得嵌套娃娃的例子嗎?)。子物件始終可以分配給祖先變數。現在記住這一點,在接下來的講座中我們將進一步分析這個過程。那我們的例子會產生什麼結果呢?
Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
instanceof 將檢查什麼:我們的類別變數Cat還是我們的類別物件MaineCoon?其實,這個問題的答案很簡單。你只需要再次閱讀我們的運算子的定義:需要instanceof運算子來檢查變數引用的物件是否是X基於某個類別創建的Yinstanceof 運算子檢查物件的來源,而不是變數。 因此,在範例中,兩次都會在控制台中顯示true:我們有一個類型為 的物件MaineCoon。當然,它是基於類別創建的MaineCoon,但也是基於父類別創建的Cat
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION