[英]What is the 'instanceof' operator used for in Java?
instanceof
運算符的用途是什么? 我見過類似的東西
if (source instanceof Button) {
//...
} else {
//...
}
但這些對我來說都沒有意義。 我做了我的研究,但只提出了沒有任何解釋的例子。
instanceof
關鍵字是一個二元運算符,用於測試對象(實例)是否是給定類型的子類型。
想象:
interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}
想象一個用Object dog = new Dog()
創建的dog
對象,然后:
dog instanceof Domestic // true - Dog implements Domestic
dog instanceof Animal // true - Dog extends Animal
dog instanceof Dog // true - Dog is Dog
dog instanceof Object // true - Object is the parent type of all objects
但是,使用Object animal = new Animal();
,
animal instanceof Dog // false
因為Animal
是Dog
的超類型,可能不太“精致”。
和,
dog instanceof Cat // does not even compile!
這是因為Dog
既不是Cat
的子類型也不是超類型,它也沒有實現它。
請注意,上面用於dog
的變量是Object
類型。 這是為了表明instanceof
是一個運行時操作,並將我們帶到一個用例:在運行時根據對象類型做出不同的反應。
注意事項: expressionThatIsNull instanceof T
對於所有類型T
都是假的。
快樂編碼。
如果表達式的左側是右側類名的實例,則它是一個返回 true 的運算符。
這樣想想。 假設您所在街區的所有房屋都是根據相同的藍圖建造的。 十個房子(對象),一套藍圖(類定義)。
當您擁有一組對象並且不確定它們是什么時, instanceof
是一個有用的工具。 假設您有一個窗體上的控件集合。 您想讀取任何復選框的已選中狀態,但您不能向普通舊對象詢問其已選中狀態。 相反,您將查看每個對象是否是一個復選框,如果是,則將其轉換為復選框並檢查其屬性。
if (obj instanceof Checkbox)
{
Checkbox cb = (Checkbox)obj;
boolean state = cb.getState();
}
如本網站所述:
instanceof
運算符可用於測試對象是否屬於特定類型...if (objectReference instanceof type)
一個簡單的例子:
String s = "Hello World!" return s instanceof String; //result --> true
但是,對空引用變量/表達式應用
instanceof
返回 false。String s = null; return s instanceof String; //result --> false
由於子類是其超類的“類型”,因此您可以使用
instanceof
來驗證這一點...class Parent { public Parent() {} } class Child extends Parent { public Child() { super(); } } public class Main { public static void main(String[] args) { Child child = new Child(); System.out.println( child instanceof Parent ); } } //result --> true
我希望這有幫助!
此運算符允許您確定對象的類型。 它返回一個boolean
值。
例如
package test;
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
public class instanceoftest
{
public static void main(String args[])
{
Map m=new HashMap();
System.out.println("Returns a boolean value "+(m instanceof Map));
System.out.println("Returns a boolean value "+(m instanceof HashMap));
System.out.println("Returns a boolean value "+(m instanceof Object));
System.out.println("Returns a boolean value "+(m instanceof Date));
}
}
輸出是:
Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false
如果source
是一個object
變量, instanceof
是一種檢查它是否是Button
。
正如其他答案中提到的, instanceof
的典型典型用法是檢查標識符是否指代更具體的類型。 例子:
Object someobject = ... some code which gets something that might be a button ...
if (someobject instanceof Button) {
// then if someobject is in fact a button this block gets executed
} else {
// otherwise execute this block
}
但是請注意,左側表達式的類型必須是右側表達式的父類型(參見JLS 15.20.2和Java Puzzlers, #50, pp114 )。 例如,以下將無法編譯:
public class Test {
public static void main(String [] args) {
System.out.println(new Test() instanceof String); // will fail to compile
}
}
這無法與消息編譯:
Test.java:6: error: inconvertible types
System.out.println(t instanceof String);
^
required: String
found: Test
1 error
因為Test
不是String
的父類。 OTOH,這可以完美編譯並按預期打印false
:
public class Test {
public static void main(String [] args) {
Object t = new Test();
// compiles fine since Object is a parent class to String
System.out.println(t instanceof String);
}
}
public class Animal{ float age; }
public class Lion extends Animal { int claws;}
public class Jungle {
public static void main(String args[]) {
Animal animal = new Animal();
Animal animal2 = new Lion();
Lion lion = new Lion();
Animal animal3 = new Animal();
Lion lion2 = new Animal(); //won't compile (can't reference super class object with sub class reference variable)
if(animal instanceof Lion) //false
if(animal2 instanceof Lion) //true
if(lion insanceof Lion) //true
if(animal3 instanceof Animal) //true
}
}
可用作等式檢查的速記。
所以這段代碼
if(ob != null && this.getClass() == ob.getClass) {
}
可以寫成
if(ob instanceOf ClassA) {
}
大多數人都正確解釋了這個問題的“什么”,但沒有人正確解釋“如何”。
所以這里有一個簡單的說明:
String s = new String("Hello");
if (s instanceof String) System.out.println("s is instance of String"); // True
if (s instanceof Object) System.out.println("s is instance of Object"); // True
//if (s instanceof StringBuffer) System.out.println("s is instance of StringBuffer"); // Compile error
Object o = (Object)s;
if (o instanceof StringBuffer) System.out.println("o is instance of StringBuffer"); //No error, returns False
else System.out.println("Not an instance of StringBuffer"); //
if (o instanceof String) System.out.println("o is instance of String"); //True
輸出:
s is instance of String
s is instance of Object
Not an instance of StringBuffer
o is instance of String
將s
與 StringBuffer 進行比較時編譯器錯誤的原因在docs 中有很好的解釋:
您可以使用它來測試對象是類的實例、子類的實例還是實現特定接口的類的實例。
這意味着 LHS 必須是 RHS 的實例或實現 RHS 或擴展 RHS 的類。
那怎么用instanceof呢?
由於每個類都擴展了 Object,因此將 LHS 類型轉換為 object 將始終對您有利:
String s = new String("Hello");
if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //No compiler error now :)
else System.out.println("Not an instance of StringBuffer");
輸出:
Not an instance of StringBuffer
當您想知道特定對象的實例時,關鍵字的實例很有用。
假設您拋出異常,當您捕獲時,然后執行 sum 自定義操作,然后再次按照您的邏輯繼續(拋出或記錄等)
示例:1) 用戶創建自定義異常“InvalidExtensionsException”並按照邏輯拋出它
2) 現在在 catch 塊中 catch (Exception e) { 如果異常類型是“InvalidExtensionsException”,則執行求和邏輯
InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;
3) 如果您不檢查實例且異常類型為空指針異常,您的代碼將中斷。
所以你的邏輯應該在 if (e instanceof InvalidExtensionsException){ InvalidExtensionsException InvalidException =(InvalidExtensionsException)e; 的實例內。 }
上面的例子是錯誤的編碼實踐 但是這個例子可以幫助你理解它的實例的使用。
最好的解釋是jls 。 始終嘗試檢查消息來源所說的內容。 在那里你會得到最好的答案以及更多。 在這里復制一些部分:
instanceof 運算符的 RelationalExpression 操作數的類型必須是引用類型或空類型; 否則,會發生編譯時錯誤。
如果 instanceof 運算符之后提到的 ReferenceType 不表示可具體化的引用類型(第 4.7 節),則會出現編譯時錯誤。
如果 RelationalExpression 到 ReferenceType 的強制轉換(第 15.16 節)將作為編譯時錯誤而被拒絕,那么關系表達式的 instanceof 同樣會產生編譯時錯誤。 在這種情況下,instanceof 表達式的結果永遠不會為真。
java instanceof
運算符用於測試對象是否為指定類型(類或子類或接口)的實例。
java 中的 instanceof 也稱為類型comparison operator
因為它將實例與類型進行比較。 它返回true
或false
。 如果我們將instanceof
運算符應用於任何具有null
值的變量,它會返回false
。
從包含JEP 305 的JDK 14+ 開始,我們還可以對instanceof
進行“模式匹配”
模式基本上測試一個值是否具有某種類型,並且當它具有匹配類型時可以從該值中提取信息。 模式匹配允許更清晰、更有效地表達系統中的公共邏輯,即從對象中有條件地移除組件。
在 Java 14 之前
if (obj instanceof String) {
String str = (String) obj; // need to declare and cast again the object
.. str.contains(..) ..
}else{
str = ....
}
Java 14 增強功能
if (!(obj instanceof String str)) {
.. str.contains(..) .. // no need to declare str object again with casting
} else {
.. str....
}
我們還可以將類型檢查和其他條件結合在一起
if (obj instanceof String str && str.length() > 4) {.. str.contains(..) ..}
在instanceof
使用模式匹配應該會減少 Java 程序中顯式轉換的總數。
PS : instanceOf
只會在對象不為空時匹配,然后才可以分配給str
。
在 JDK 16 中引入了 instanceof 的模式匹配。
前:
if (obj instanceof StringBuilder) {
StringBuilder builder = (StringBuilder) obj;
builder.append("Hello StackOverflow")
}
現在:
if (obj instanceof StringBuilder builder) {
builder.append("Hello StackOverflow")
}
前:
public boolean equals(Object o) {
if (!(o instanceof StringBuilder)) {
return false;
}
StringBuilder other = (StringBuilder) o;
return //Logic
}
現在:
public boolean equals(Object o) {
return (o instanceof StringBuilder other)
//Logic
}
當 object(listObj) 中存在的元素類型在運行時未知時,也可以使用instanceof運算符。 在這些情況下, instanceof 運算符可用於確定元素類型,並將有助於根據需求進一步進行。
例如 :
String str = "";
int a = 0;
Integer b = null;
List listObj = new ArrayList<>();
listObj.add("String");
listObj.add(100);
listObj.add(10.5);
listObj.add(1l);
if (listObj.get(0) instanceof String) {
System.out.println("String");
str = (String)listObj.get(0);
}
if (listObj.get(1) instanceof Integer) {
System.out.println("Integer");
a = (int)listObj.get(1);
b = (Integer)listObj.get(1);
}
if (listObj.get(2) instanceof Double) {
System.out.println("Double");
}
if (listObj.get(3) instanceof Long) {
System.out.println("Long");
}
如果從對象檢索的值分配給變量,JVM 會要求您在編譯時將其轉換為特定類型。
讓我們考慮:
int x = (String)listObj.get(0);
// 在上面的例子中,從 listObj 檢索到的元素是 String 並且被轉換為 int。 這將解決編譯時錯誤。但在執行時 JVM 會拋出 ClassCastException。
因此,我們可以使用 instanceof 運算符檢查並將值分配給正確的變量以避免錯誤,而不是將值隨機分配給與類型不匹配的變量。
instanceof 運算符將對象與指定類型進行比較。 您可以使用它來測試對象是類的實例、子類的實例還是實現特定接口的類的實例。
http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
class Test48{
public static void main (String args[]){
Object Obj=new Hello();
//Hello obj=new Hello;
System.out.println(Obj instanceof String);
System.out.println(Obj instanceof Hello);
System.out.println(Obj instanceof Object);
Hello h=null;
System.out.println(h instanceof Hello);
System.out.println(h instanceof Object);
}
}
您可以使用 Map 對實例進行更高的抽象
private final Map<Class, Consumer<String>> actions = new HashMap<>();
然后讓這樣的地圖向它添加一些動作:
actions.put(String.class, new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("action for String");
}
};
然后擁有一個未知類型的對象,您可以從該地圖中獲取特定操作:
actions.get(someObject).accept(someObject)
instanceof 運算符用於檢查對象是否為指定類型的實例。 (類或子類或接口)。
instanceof 也稱為類型比較運算符,因為它將實例與類型進行比較。 它返回真或假。
class Simple1 {
public static void main(String args[]) {
Simple1 s=new Simple1();
System.out.println(s instanceof Simple1); //true
}
}
如果我們將 instanceof 運算符應用於任何具有 null 值的變量,它將返回 false。
非常簡單的代碼示例:
If (object1 instanceof Class1) {
// do something
} else if (object1 instanceof Class2) {
// do something different
}
這里要小心。 在上面的示例中,如果 Class1 是 Object,則第一次比較將始終為真。 所以,就像有例外一樣,等級順序很重要!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.