สิ่งที่เป็นinstanceof
ผู้ประกอบการใช้? ฉันเคยเห็นสิ่งที่ชอบ
if (source instanceof Button) {
//...
} else {
//...
}
แต่มันก็ไม่สมเหตุสมผลสำหรับฉัน ฉันทำวิจัยแล้ว แต่มีตัวอย่างมาโดยไม่มีคำอธิบายใด ๆ
instanceof
เมื่อเอาชนะequals
?
สิ่งที่เป็นinstanceof
ผู้ประกอบการใช้? ฉันเคยเห็นสิ่งที่ชอบ
if (source instanceof Button) {
//...
} else {
//...
}
แต่มันก็ไม่สมเหตุสมผลสำหรับฉัน ฉันทำวิจัยแล้ว แต่มีตัวอย่างมาโดยไม่มีคำอธิบายใด ๆ
instanceof
เมื่อเอาชนะequals
?
คำตอบ:
instanceof
keyword เป็นตัวดำเนินการไบนารีที่ใช้ในการทดสอบว่าวัตถุ (อินสแตนซ์) เป็นประเภทย่อยของประเภทที่กำหนด
Imagine:
interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}
ลองนึกภาพdog
วัตถุที่สร้างขึ้นObject dog = new 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
ไม่ใช่ประเภทย่อยหรือ supertype ของCat
และมันก็ไม่ได้ใช้มัน
โปรดทราบว่าตัวแปรที่ใช้สำหรับการดังกล่าวข้างต้นเป็นประเภทdog
Object
นี้คือการแสดงinstanceof
เป็นรันไทม์การดำเนินงานและนำเราไปสู่การ / กรณีใช้: การตอบสนองตามที่แตกต่างกันเมื่อวัตถุประเภทที่รันไทม์
สิ่งที่ควรทราบ: เป็นเท็จชนิดทั้งหมดexpressionThatIsNull instanceof T
T
การเข้ารหัสที่มีความสุข
Object dog = new Dog(); System.out.println(dog instanceof Cat);
. คอมไพล์นี้ใช้ได้ดีและพิมพ์false
ออกมา คอมไพเลอร์ไม่ได้รับอนุญาตให้กำหนด ณ เวลารวบรวมที่dog
ไม่สามารถเป็น Cat (ตามกฎใน JLS)
boolean b = "foo" instanceof Integer;
Object indirect = ...; if (indirect instanceof Something)
คำตอบที่เป็นเรื่องเกี่ยวกับ มันไม่เกี่ยวกับif (literal instanceof Something)
อย่างที่คุณคิด
Object dog
ส่วนนี้ไปแล้ว ความผิดฉันเอง!
dog instanceof Cat // does not even compile!
(เพราะเป็นคลาส) หากCat
เป็นอินเทอร์เฟซก็จะรวบรวม
มันเป็นโอเปอเรเตอร์ที่คืนค่าจริงถ้าด้านซ้ายของนิพจน์เป็นตัวอย่างของชื่อคลาสทางด้านขวา
คิดแบบนี้ สมมติว่าบ้านทั้งหมดในบล็อกของคุณถูกสร้างขึ้นจากพิมพ์เขียวเดียวกัน บ้านสิบหลัง (วัตถุ), พิมพ์เขียวหนึ่งชุด (คำจำกัดความของชั้นเรียน)
instanceof
เป็นเครื่องมือที่มีประโยชน์เมื่อคุณมีชุดของวัตถุและคุณไม่แน่ใจว่ามันคืออะไร สมมติว่าคุณมีชุดควบคุมบนฟอร์ม คุณต้องการที่จะอ่านสถานะการตรวจสอบของสิ่งที่มีช่องทำเครื่องหมาย แต่คุณไม่สามารถถามวัตถุเก่าธรรมดาสำหรับสถานะการตรวจสอบ แต่คุณจะเห็นว่าแต่ละวัตถุเป็นช่องทำเครื่องหมายหรือไม่และถ้าเป็นให้โยนมันไปที่ช่องทำเครื่องหมายและตรวจสอบคุณสมบัติ
if (obj instanceof Checkbox)
{
Checkbox cb = (Checkbox)obj;
boolean state = cb.getState();
}
instanceof
สามารถทำให้ปลอดภัยที่จะลดลง
ตามที่อธิบายไว้ในเว็บไซต์นี้ :
instanceof
ผู้ประกอบการสามารถใช้ในการทดสอบว่าวัตถุเป็นประเภทที่เฉพาะเจาะจง ...if (objectReference instanceof type)
ตัวอย่างรวดเร็ว:
String s = "Hello World!" return s instanceof String; //result --> true
อย่างไรก็ตามการใช้
instanceof
กับตัวแปร / นิพจน์อ้างอิงเป็น null จะส่งคืนค่าเท็จ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 จะอธิบายได้ดีในเอกสาร :
คุณสามารถใช้มันเพื่อทดสอบว่าวัตถุเป็นอินสแตนซ์ของคลาสอินสแตนซ์ของคลาสย่อยหรืออินสแตนซ์ของคลาสที่ใช้อินเทอร์เฟซเฉพาะ
ซึ่งแสดงถึง LHS จะต้องเป็นตัวอย่างของ RHS หรือคลาสที่ใช้ RHS หรือขยาย RHS
วิธีการใช้งานใช้งานอินสแตนซ์แล้ว?
เนื่องจากคลาสทุกคลาสจะขยายอ็อบเจกต์ LHS การพิมพ์ลงไปที่อ็อบเจกต์จะทำงานได้ตามที่คุณต้องการ:
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
if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //shouldn't this be true
ไม่เนื่องจากเราพิมพ์ตัวอักษรเป็น Object
ตัวดำเนินการ instanceof เปรียบเทียบวัตถุกับชนิดที่ระบุ คุณสามารถใช้มันเพื่อทดสอบว่าวัตถุเป็นอินสแตนซ์ของคลาสอินสแตนซ์ของคลาสย่อยหรืออินสแตนซ์ของคลาสที่ใช้อินเทอร์เฟซเฉพาะ
http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
อินสแตนซ์ของคำหลักมีประโยชน์เมื่อคุณต้องการทราบอินสแตนซ์ของวัตถุเฉพาะ
สมมติว่าคุณกำลังโยนข้อยกเว้นและเมื่อคุณได้จับแล้วทำการดำเนินการที่กำหนดเองผลรวมแล้วดำเนินการต่อตามตรรกะของคุณอีกครั้ง (โยนหรือบันทึก ฯลฯ )
ตัวอย่าง: 1) ผู้ใช้สร้างข้อยกเว้นที่กำหนดเอง "InvalidExtensionsException" และโยนตามตรรกะ
2) ตอนนี้อยู่ใน catch catch catch (Exception e) {ใช้ตรรกะผลรวมหากประเภทการยกเว้นเป็น "InvalidExtensionsException"
InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;
3) หากคุณไม่ได้ตรวจสอบอินสแตนซ์ของและประเภทการยกเว้นเป็นตัวชี้ Null ยกเว้นรหัสของคุณจะแตก
ดังนั้นตรรกะของคุณควรอยู่ในอินสแตนซ์ของ if (e instanceof InvalidExtensionsException) {InvalidExtensionsException InvalidException = (InvalidExtensionsException) e; }
ตัวอย่างข้างต้นคือการฝึกเขียนโค้ดที่ผิดอย่างไรก็ตามตัวอย่างนี้ช่วยให้คุณเข้าใจการใช้งานอินสแตนซ์ของมัน
คำอธิบายที่ดีที่สุดคือJLS พยายามตรวจสอบแหล่งที่มาพูดเสมอ แล้วคุณจะได้รับคำตอบที่ดีที่สุดบวกกับอีกมากมาย ผลิตซ้ำบางส่วนที่นี่:
ชนิดของตัวถูกดำเนินการ Relational Expression ของตัวดำเนินการ instanceof ต้องเป็นชนิดการอ้างอิงหรือชนิด null มิฉะนั้นจะเกิดข้อผิดพลาดในการคอมไพล์เวลา
มันเป็นข้อผิดพลาดในการคอมไพล์เวลาถ้า ReferenceType ที่กล่าวถึงหลังจากตัวดำเนินการ instanceof ไม่แสดงประเภทการอ้างอิงที่สามารถใช้ซ้ำได้ (§4.7)
หากการร่าย (§15.16) ของ Relational Expression ไปยัง ReferenceType จะถูกปฏิเสธว่าเป็นข้อผิดพลาดในการคอมไพล์เวลาดังนั้นอินสแตนซ์ของนิพจน์เชิงสัมพันธ์จะสร้างข้อผิดพลาดในการคอมไพล์ในเวลาเดียวกัน ในสถานการณ์เช่นนี้ผลลัพธ์ของการแสดงออกของอินสแตนซ์ไม่อาจเป็นจริง
ตัวinstanceof
ดำเนินการjava ถูกใช้เพื่อทดสอบว่าวัตถุเป็นอินสแตนซ์ของชนิดที่ระบุ (คลาสหรือคลาสย่อยหรืออินเทอร์เฟซ)
อินสแตนซ์ของ java เป็นที่รู้จักกันว่าเป็นประเภทcomparison operator
เพราะมันเปรียบเทียบอินสแตนซ์ที่มีประเภท ก็จะส่งกลับอย่างใดอย่างหนึ่งหรือtrue
false
ถ้าเราใช้instanceof
ผู้ประกอบการที่มีตัวแปรใด ๆ ที่มีค่าก็จะส่งกลับnull
false
จาก JDK 14+ ซึ่งรวมถึงJEP 305เรายังสามารถทำ "การจับคู่รูปแบบ" สำหรับ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
เท่านั้น
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);
}
}
ตัวอย่างรหัสง่าย ๆ :
If (object1 instanceof Class1) {
// do something
} else if (object1 instanceof Class2) {
// do something different
}
ระวังที่นี่ ในตัวอย่างด้านบนหาก Class1 เป็น 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 ถูกใช้เพื่อตรวจสอบว่าวัตถุเป็นอินสแตนซ์ของชนิดที่ระบุ (คลาสหรือคลาสย่อยหรืออินเตอร์เฟส)
อินสแตนซ์ของมันยังเป็นที่รู้จักกันในนามผู้ดำเนินการเปรียบเทียบประเภทเพราะมันเปรียบเทียบอินสแตนซ์ที่มีประเภท มันจะส่งกลับทั้งจริงหรือเท็จ
class Simple1 {
public static void main(String args[]) {
Simple1 s=new Simple1();
System.out.println(s instanceof Simple1); //true
}
}
ถ้าเราใช้ตัวดำเนินการ instanceof กับตัวแปรใด ๆ ที่มีค่า Null มันจะคืนค่าเท็จ