CodeGym /Java Blog /Toto sisi /Java instanceof 運算符
John Squirrels
等級 41
San Francisco

Java instanceof 運算符

在 Toto sisi 群組發布
你好!今天我們將討論instanceof運算符,考慮其使用方式的示例,並探討其工作原理的某些方面:) 您已經在 CodeGym 的早期級別遇到過此運算符。你還記得我們為什麼需要它嗎?如果沒有,不用擔心。讓我們一起記住。需要instanceof運算符來檢查X變量引用的對像是否基於某個Y類創建的。這聽起來很簡單。我們為什麼回到這個話題?首先,因為現在您已經非常熟悉 Java 的繼承機制和 OOP 的其他原則。instanceof運算符現在會更加清晰,我們將查看有關如何使用它的更高級示例我們走吧!instanceof 運算符如何工作 - 1您可能還記得,如果檢查結果為真,則instanceof運算符返回,如果表達式為假,則返回假。因此,它通常出現在各種條件表達式中(if…else)。讓我們從一些更簡單的例子開始:

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
您認為控制台上會顯示什麼?好吧,這裡很明顯。:) x對像是一個整數,所以結果將為true。控制台輸出: True 讓我們嘗試檢查它是否是一個String

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
我們得到一個錯誤。並註意:編譯器在運行代碼之前產生了錯誤!馬上就看出IntegerString不能自動相互轉換,也沒有繼承關係。因此,不會基於String創建 Integer 對象。這很方便並且有助於避免奇怪的運行時錯誤,因此編譯器在這裡幫助了我們 :) 現在讓我們嘗試考慮更困難的示例。由於我們提到了繼承,讓我們使用以下小類系統:

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
我們已經知道在檢查一個對像是否是一個類的實例時instanceof 的行為 如何,但是如果我們考慮父子關係會發生什麼?例如,您認為這些表達式會產生什麼結果:

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究竟如何解釋“基於類創建的對象”?' cat instanceof Animal ' 的計算結果為true,但我們肯定可以挑出該措辭的錯誤。為什麼要基於Animal類創建Cat對象?不就是單獨根據自己的類創建的嗎?答案很簡單,您可能已經想到了。記住創建對象時調用構造函數和初始化變量的順序。我們已經在關於類構造函數的文章中介紹了這個主題。這是該課的一個例子:

public class Animal {

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

   public static int animalCount = 7700000;

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

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

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

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

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
如果您在 IDE 中運行它,控制台輸出將如下所示: Animal base class constructor is running Animal 類的變量是否已經初始化?靜態變量animalCount當前值=7700000 Animal類brain當前值=Animal類brain初始值Animal類heart當前值=Animal類heart初始值已有Cat類變量初始化了嗎?靜態變量的當前值 catCount = 37 Animal 基類構造完成!brain 當前值 = Brain 當前值 heart = Heart cat 類構造函數已經啟動(Animal 構造函數已經完成) 靜態變量 catCount 當前值 = 37 tail 當前值 = Cat 類中 tail 的初始值 tail 當前值 =尾巴 現在你還記得嗎?:) 基類的構造函數,如果有基類,在創建對象時總是先被調用。instanceof運算符在嘗試確定A對像是否基於B類創建時受此原則指導。如果調用了基類的構造函數,那麼就可以毫無疑問了。通過第二次檢查,一切都變得更簡單了:

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是一個short:它很容​​易適合一個long變量,因為有足夠的字節來容納它(還記得娃娃的例子嗎?)。 後代對象總是可以分配給祖先變量。現在,只需記住這一點,在後續課程中我們將分析它是如何工作的。那麼我們的例子輸出了什麼?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
instanceof 會檢查什麼?我們的Cat變量還是我們的MaineCoon對象?答案是這個問題其實很簡單。你只需要再次閱讀運算符的定義:需要instanceof運算符來檢查X變量引用的對像是否基於某個Y類創建。instanceof運算符測試對象的來源,而不是變量類型因此,在此示例中,我們的程序將在兩種情況下都顯示為真:我們有一個MaineCoon對象。很明顯,它是基於MaineCoon類創建的,但它是基於Cat創建的還有家長班!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION