String x = (String) null;
ทำไมไม่มีข้อยกเว้นในคำชี้แจงนี้
String x = null;
System.out.println(x);
null
มันพิมพ์ แต่.toString()
วิธีการควรโยนข้อยกเว้นตัวชี้โมฆะ
String x = (String) null;
ทำไมไม่มีข้อยกเว้นในคำชี้แจงนี้
String x = null;
System.out.println(x);
null
มันพิมพ์ แต่.toString()
วิธีการควรโยนข้อยกเว้นตัวชี้โมฆะ
คำตอบ:
คุณสามารถส่งnull
ไปยังประเภทการอ้างอิงใด ๆ โดยไม่มีข้อยกเว้น
println
วิธีไม่เคยโยนชี้โมฆะเพราะมันตรวจสอบก่อนว่าวัตถุเป็นโมฆะหรือไม่ หาก null "null"
แล้วมันก็พิมพ์สตริง มิฉะนั้นจะเรียกtoString
วิธีการของวัตถุนั้น
การเพิ่มรายละเอียดเพิ่มเติม:วิธีการพิมพ์วิธีการโทรString.valueOf(object)
ภายในบนวัตถุอินพุต และในvalueOf
วิธีการตรวจสอบนี้จะช่วยหลีกเลี่ยงข้อยกเว้นตัวชี้โมฆะ:
return (obj == null) ? "null" : obj.toString();
สำหรับส่วนที่เหลือของความสับสนของคุณเรียกวิธีการใด ๆ กับวัตถุ null ควรโยนข้อยกเว้นตัวชี้โมฆะถ้าไม่ใช่กรณีพิเศษ
คุณสามารถส่งnull
ไปอ้างอิงได้ทุกประเภท นอกจากนี้คุณยังสามารถเรียกใช้เมธอดที่จัดการnull
กับอาร์กิวเมนต์เช่นSystem.out.println(Object)
ทำได้ แต่คุณไม่สามารถอ้างอิงnull
ค่าและเรียกใช้เมธอดนั้นได้
BTW มีสถานการณ์ที่ยุ่งยากซึ่งปรากฏว่าคุณสามารถเรียกใช้เมธอดสแตติกเกี่ยวกับnull
ค่า
Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
t.yield() -> Thread.yeld()
หรือไม่ คล้ายกับวิธีการfinal int i = 1; while (i == 1)
ปรับให้เหมาะกับwhile(true)
นี่คือโดยการออกแบบ คุณสามารถส่งnull
ไปอ้างอิงได้ทุกประเภท มิฉะนั้นคุณจะไม่สามารถกำหนดให้กับตัวแปรอ้างอิงได้
การกำหนดค่า null จำเป็นต้องใช้สำหรับการสร้างต่อไปนี้เมื่อเมธอดถูกโหลดมากเกินไปและหากโมฆะถูกส่งไปยังเมธอดที่โอเวอร์โหลดเหล่านี้คอมไพเลอร์ไม่ทราบวิธีการล้างความคลุมเครือดังนั้นเราจำเป็นต้องพิมพ์ null ในกรณีนี้
class A {
public void foo(Long l) {
// do something with l
}
public void foo(String s) {
// do something with s
}
}
new A().foo((String)null);
new A().foo((Long)null);
มิฉะนั้นคุณไม่สามารถเรียกวิธีที่คุณต้องการ
String bar = null;
ปลดเปลื้องมูลค่าให้กับnull
String
จนถึงตอนนี้ฉันแค่ต้องทิ้งค่า null อย่างชัดเจนในการทดสอบที่มีวิธีการมากเกินไปและฉันต้องการทดสอบพฤติกรรมของมันด้วยอินพุตว่าง ยังดีที่ฉันรู้ว่าฉันกำลังจะเขียนคำตอบที่คล้ายกันก่อนที่ฉันจะพบคุณ
l instanceof Long
และs instanceof String
จะกลับมาfalse
ในกรณีเหล่านี้
Println(Object)
การใช้งาน String.valueOf()
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Print(String)
ไม่ตรวจสอบเป็นโมฆะ
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
คำตอบมากมายที่นี่พูดถึงแล้ว
คุณสามารถใช้ค่าอ้างอิงใด ๆ ก็ได้
และ
ถ้าอาร์กิวเมนต์เป็นโมฆะสตริงจะเท่ากับ "null"
ฉันสงสัยว่ามีการระบุไว้ที่ไหนและค้นหาข้อมูลจำเพาะ Java:
การอ้างอิงที่เป็นโมฆะสามารถกำหนดหรือส่งต่อไปยังประเภทการอ้างอิงใด ๆ (§5.2, §5.3, §5.5)
หากการอ้างอิงเป็นโมฆะมันจะถูกแปลงเป็นสตริง "null" (อักขระ ASCII สี่ตัว n, u, l, l)
อย่างที่คนอื่นเขียนคุณสามารถทิ้งทุกสิ่งได้ โดยปกติแล้วคุณไม่ต้องการสิ่งนั้นคุณสามารถเขียน:
String nullString = null;
โดยไม่ต้องใส่นักแสดงที่นั่น
แต่มีบางโอกาสที่บรรยากาศแบบนั้นมีเหตุผล:
ก) หากคุณต้องการแน่ใจว่าวิธีการเฉพาะนั้นถูกเรียกเช่น:
void foo(String bar) { ... }
void foo(Object bar) { ... }
จากนั้นมันจะสร้างความแตกต่างถ้าคุณพิมพ์
foo((String) null) vs. foo(null)
b) ถ้าคุณตั้งใจจะใช้ IDE เพื่อสร้างรหัส ตัวอย่างเช่นฉันมักจะเขียนการทดสอบหน่วยเช่น:
@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
new MyClassUnderTest((Whatever) null);
}
ฉันกำลังทำ TDD นี่หมายความว่าคลาส "MyClassUnderTest" อาจยังไม่มีอยู่ โดยการเขียนรหัสนั้นฉันสามารถใช้ IDE ของฉันเพื่อสร้างคลาสใหม่ก่อน และจากนั้นสร้างนวกรรมิกยอมรับ "อะไรก็ตาม" อาร์กิวเมนต์ "ออกจากกล่อง" - IDE สามารถคิดจากการทดสอบของฉันที่นวกรรมิกควรใช้อาร์กิวเมนต์ชนิดใดก็ตาม
วิธีนี้มีประโยชน์มากเมื่อใช้วิธีที่ไม่ชัดเจน ตัวอย่างเช่น: JDialog มีตัวสร้างที่มีลายเซ็นต่อไปนี้:
JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)
ฉันต้องใช้ตัวสร้างนี้เพราะฉันต้องการตั้งค่า GraphicsConfiguration แต่ฉันไม่มี parent สำหรับไดอะล็อกนี้ดังนั้นอาร์กิวเมนต์แรกควรเป็นค่าว่าง การใช้
JDialog(null, String, boolean, Graphicsconfiguration)
คลุมเครือดังนั้นในกรณีนี้ฉันสามารถ จำกัด การโทรให้แคบลงได้โดยใช้ประเภทใดประเภทหนึ่งที่รองรับ:
JDialog((Frame) null, String, boolean, GraphicsConfiguration)
คุณสมบัติภาษานี้สะดวกในสถานการณ์นี้
public String getName() {
return (String) memberHashMap.get("Name");
}
หาก memberHashMap.get ("ชื่อ") ส่งคืนค่า null คุณยังคงต้องการวิธีการด้านบนเพื่อคืนค่า Null โดยไม่ส่งข้อยกเว้น ไม่ว่าคลาสจะเป็นอะไรก็ตาม null เป็นโมฆะ