หากคลาสB
และคลาสC
ขยายคลาสA
และฉันมีอ็อบเจกต์ประเภทB
หรือC
ฉันจะกำหนดประเภทที่เป็นอินสแตนซ์ได้อย่างไร
หากคลาสB
และคลาสC
ขยายคลาสA
และฉันมีอ็อบเจกต์ประเภทB
หรือC
ฉันจะกำหนดประเภทที่เป็นอินสแตนซ์ได้อย่างไร
คำตอบ:
if (obj instanceof C) {
//your code
}
if(!(obj instanceof C))
code
Child1 child1 ต่อไปนี้= new Child1 (); Parent1 parentChild = new Child2 (); Child2 child2 = new Child2 (); (child1 อินสแตนซ์ของ Parent1); (child1 อินสแตนซ์ของ Child1); (parentChild instanceof Child2); (parentChild instanceof Parent1); (parentChild instanceof Child1); code
มันอาจชัดเจนเจตนาของอินสแตนซ์ของ
ใช้Object.getClass () ส่งคืนประเภทรันไทม์ของวัตถุ
มีการนำเสนอคำตอบที่ถูกต้องหลายคำ แต่ยังมีวิธีการเพิ่มเติม: Class.isAssignableFrom()
และพยายามที่จะโยนวัตถุ (ซึ่งอาจส่งClassCastException
)
ขอสรุปวิธีที่เป็นไปได้ในการทดสอบว่าวัตถุobj
เป็นตัวอย่างของประเภทหรือไม่C
:
// Method #1
if (obj instanceof C)
;
// Method #2
if (C.class.isInstance(obj))
;
// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
;
// Method #4
try {
C c = (C) obj;
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
// Method #5
try {
C c = C.class.cast(obj);
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
null
การจัดการมีความแตกต่างในการnull
จัดการว่า:
false
ว่าถ้าobj
เป็นnull
( null
ไม่ใช่ตัวอย่างของอะไร)NullPointerException
ชัดขึ้นnull
เพราะnull
สามารถใช้กับทุกประเภท!ข้อควรจำ:
null
ไม่ใช่ตัวอย่างทุกประเภท แต่สามารถส่งไปเป็นประเภทใดก็ได้
Class.getName()
ไม่ควรใช้เพื่อทำการทดสอบ"is-instance-of"ถ้าวัตถุไม่ได้เป็นประเภทC
แต่เป็นคลาสย่อยของมันมันอาจมีชื่อและแพคเกจที่แตกต่างกันโดยสิ้นเชิง (ดังนั้นชื่อคลาสจะไม่ตรงกัน) แต่เป็น C
ยังคงเป็นประเภทClass.isAssignableFrom()
ไม่สมมาตร : obj.getClass().isAssignableFrom(C.class)
จะกลับมาfalse
ถ้าประเภทของการobj
เป็น subclass C
ของคุณสามารถใช้ได้:
Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object
HTH แต่ฉันคิดว่าส่วนใหญ่แล้วมันก็ไม่ใช่วิธีปฏิบัติที่ดีที่จะใช้มันเพื่อควบคุมโฟลว์หรืออะไรทำนองนั้น ...
การใช้วิธีการใด ๆ ที่แนะนำถือว่าเป็นกลิ่นรหัสซึ่งมีพื้นฐานมาจากการออกแบบ OO ที่ไม่ดี
หากการออกแบบของคุณเป็นสิ่งที่ดีที่คุณไม่ควรพบว่าตัวเองจำเป็นต้องใช้หรือgetClass()
instanceof
วิธีการใด ๆ ที่แนะนำจะทำ แต่เพียงสิ่งที่ควรคำนึงถึงการออกแบบที่ชาญฉลาด
เราสามารถใช้การสะท้อนในกรณีนี้
objectName.getClass().getName();
ตัวอย่าง:-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getClass().getName();
}
ในกรณีนี้คุณจะได้รับชื่อของคลาสที่อ็อบเจกต์ส่งผ่านไปยังHttpServletRequest
ตัวแปรผู้อ้างอิงของอินเทอร์เฟซ
obj.getClass()
จะส่งกลับ className นำหน้าด้วยคำว่าclass
request.getClass().getName();
พิมพ์แพ็คเกจทั้งหมด! พร้อมกับชื่อคลาส
นอกจากนี้ยังมี.isInstance
วิธีการในClass
คลาส "" ถ้าคุณได้คลาสของวัตถุผ่านmyBanana.getClass()
คุณสามารถดูว่าวัตถุของคุณmyApple
เป็นอินสแตนซ์ของคลาสเดียวกันกับmyBanana
ผ่านหรือไม่
myBanana.getClass().isInstance(myApple)
การตรวจสอบด้วยisinstance()
จะไม่เพียงพอหากคุณต้องการทราบในเวลาทำงาน ใช้:
if(someObject.getClass().equals(C.class){
// do something
}
ฉันใช้ฟังก์ชั่นการเป่าในคลาส GeneralUtils ของฉันตรวจสอบว่าอาจมีประโยชน์
public String getFieldType(Object o) {
if (o == null) {
return "Unable to identify the class name";
}
return o.getClass().getName();
}
ฉันใช้ Java 8 generics เพื่อรับอินสแตนซ์ของวัตถุที่ runtime แทนที่จะต้องใช้ตัวพิมพ์สลับ
public <T> void print(T data) {
System.out.println(data.getClass().getName()+" => The data is " + data);
}
ผ่านประเภทข้อมูลใด ๆ และวิธีการจะพิมพ์ประเภทของข้อมูลที่คุณส่งผ่านในขณะที่เรียกมัน เช่น
String str = "Hello World";
int number = 10;
double decimal = 10.0;
float f = 10F;
long l = 10L;
List list = new ArrayList();
print(str);
print(number);
print(decimal);
print(f);
print(l);
print(list);
ต่อไปนี้เป็นผลลัพธ์
java.lang.String => The data is Hello World
java.lang.Integer => The data is 10
java.lang.Double => The data is 10.0
java.lang.Float => The data is 10.0
java.lang.Long => The data is 10
java.util.ArrayList => The data is []