簡體   English   中英

Java 中使用的“instanceof”運算符是什么?

[英]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

因為AnimalDog的超類型,可能不太“精致”。

和,

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.2Java 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因為它將實例與類型進行比較。 它返回truefalse 如果我們將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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM