ความแตกต่างระหว่างสตริง Java กับ null (“”)


151

ความแตกต่างระหว่างnullและ""(สตริงว่าง) คืออะไร?

ฉันได้เขียนโค้ดง่ายๆ

String a = "";
String b = null;

System.out.println(a == b); // false
System.out.println(a.equals(b)); // false

falseงบทั้งสองกลับ ดูเหมือนว่าฉันไม่สามารถค้นหาความแตกต่างที่แท้จริงระหว่างพวกเขาได้


6
เปรียบเทียบกับb.equals(a)- แต่ไม่ใช้==สำหรับการเปรียบเทียบสตริงเนื่องจาก "ไม่ทำงาน" ในวิธีอื่น nullค่า (ซึ่งแตกต่างจากสตริงที่ว่างเปล่า"", อินสแตนซ์ที่ถูกต้อง String) จะไม่เคยมีวิธีเรียกกับมัน การวาง "รู้จักไม่เป็นโมฆะ" (มักจะเป็นค่าคงที่หรือตามตัวอักษร) ทางด้านซ้ายของความเท่าเทียมกันคือ "โยดาเงื่อนไข" หรือบางอย่างเช่น

คำตอบ:


220

"" เป็นสตริงจริงแม้ว่าจะเป็นสตริงว่าง

อย่างไรก็ตาม null หมายความว่าตัวแปร String ชี้ไปที่ไม่มีอะไร

a==b ส่งกลับค่าเท็จเพราะ "" และโมฆะไม่ได้ใช้พื้นที่ในหน่วยความจำเท่ากันกล่าวคือตัวแปรของพวกเขาไม่ได้ชี้ไปที่วัตถุเดียวกัน

a.equals(b) ผลตอบแทนที่ผิดเพราะ "" ไม่เท่ากับ null อย่างชัดเจน

ความแตกต่างคือเนื่องจาก "" เป็นสตริงจริงคุณยังสามารถเรียกใช้เมธอดหรือฟังก์ชั่นที่ต้องการได้

a.length()

a.substring(0, 1)

และอื่น ๆ

ถ้า String เท่ากับ null เช่น b, Java จะขว้างNullPointerExceptionถ้าคุณลองเรียกใช้พูด:

b.length()


หากความแตกต่างที่คุณสงสัยคือ == เทียบกับเท่ากับนี่คือ:

== เปรียบเทียบการอ้างอิงเช่นถ้าฉันไป

String a = new String("");
String b = new String("");
System.out.println(a==b);

นั่นจะให้ผลเป็นเท็จเพราะฉันจัดสรรวัตถุสองชนิดที่แตกต่างกันและจุด a และ b ไปยังวัตถุอื่น

อย่างไรก็ตามa.equals(b)ในกรณีนี้จะคืนค่าเป็นจริงเพราะequalsสำหรับ Strings จะคืนค่าเป็นจริงถ้าหากอาร์กิวเมนต์ของสายอักขระนั้นไม่ใช่ null และแสดงถึงลำดับของอักขระที่เหมือนกัน

ถูกเตือนว่า Java มีกรณีพิเศษสำหรับ Strings

String a = "abc";
String b = "abc";
System.out.println(a==b);

คุณจะคิดว่าผลลัพธ์จะเป็นfalseเพราะมันควรจัดสรรสองสายที่แตกต่างกัน ที่จริงแล้ว Java จะฝึกงานสตริงตัวอักษร (คนที่เริ่มต้นเช่น a และ b ในตัวอย่างของเรา) ดังนั้นโปรดระวังเพราะนั่นอาจให้ผลบวกเท็จกับวิธีการ == ทำงาน


สิ่งนี้ใช้ได้กับ C # ด้วยหรือไม่ เช่นเดียวกับในแถวของ "" คือ {'\ 0'} null
Cole Johnson

3
ลิงค์เกี่ยวกับinternหมดอายุแล้ว คุณสามารถอ้างอิงไปยังเว็บไซต์อื่นเพื่ออ่านเกี่ยวกับมัน: weblogs.java.net/blog/enicholas/archive/2006/06/…
Alston

ดังนั้นถ้าฉันมีสตริงเป็นโมฆะString a = nullและจากนั้นฉันผนวกมันเป็นสตริงเช่นa+= "example"เมื่อฉันพิมพ์มันทำไมจะแสดงnullexampleถ้าเป็นโมฆะไม่ใช่สตริง?
cpinamtz

@PinaGamer JavaScript อนุญาตให้เพิ่มสตริงที่ไม่ใช่สตริงได้ จะช่วยให้คุณสตริง"num: " + 20 "num: 20"นี่หมายความว่า20เป็นสตริงหรือไม่? (ไม่ใช่20เป็นตัวเลข) กรณีเดียวกันสำหรับnull: ไม่ใช่สตริง แต่สามารถแปลงเป็นสตริงได้หากคุณพยายามเพิ่ม
daboross

@Zach L: เมื่อ String s = null + "a"; มันให้เอาท์พุท nulla แต่ null.concat ("a") มันให้ข้อยกเว้นตัวชี้โมฆะ อะไรคือเหตุผลในกรณีแรกของฉัน null + "a"; กำลังทำงาน
Ved Prakash

249

คุณอาจเข้าใจความแตกต่างระหว่าง null และสตริงว่างด้วยวิธีนี้

ความแตกต่างระหว่าง null และ 0 / สตริงว่าง

ภาพต้นฉบับโดย R. Sato ( @raysato )


7
มันเยี่ยมมาก! ฉันอธิบายว่างเปล่ากับใครบางคนและเกิดขึ้นกับคำตอบของคุณ แนวคิดคลิกทันทีสำหรับพวกเขา
matt.fc

14

String เป็นวัตถุและสามารถเป็นโมฆะ

null หมายความว่าวัตถุ String ไม่ได้เริ่มต้น

"" เป็นค่าจริงของสตริงวัตถุที่มีอินสแตนซ์เช่น "aaa"

นี่คือลิงค์ที่อาจชี้แจงจุดที่http://download.oracle.com/javase/tutorial/java/concepts/object.html


"null หมายความว่าวัตถุ String ไม่ได้สร้างอินสแตนซ์" - ขอบคุณ! ที่ช่วยให้ฉันเข้าใจสิ่งต่าง ๆ มากมาย ฉันสามารถใช้คำสั่ง if บนวัตถุ MediaPlayer เพียงครั้งเดียวและทำงานเพื่อใช้ null เพื่อตรวจสอบว่ามันทำงานหรือไม่ (ด้วยวิธีการดำเนินการถ้ามันเป็น) แต่ฉันไม่เคยเข้าใจว่าทำไมมันทำงาน แต่ตอนนี้ ฉันเห็นสิ่งที่มันพูดว่าฉันถูกตรวจสอบว่าได้รับการ MediaPlayer instantiated หรือไม่โดยใช้ null ... if (mp==null){do something}เช่น
Azurespot

12

สิ่งที่ข้อความของคุณกำลังบอกคุณคือ "" นั้นไม่เหมือนกับ null - ซึ่งเป็นจริง "" เป็นสตริงว่าง null หมายถึงไม่มีการกำหนดค่า

มันอาจจะเป็น enlightening ที่จะลอง:

System.out.println(a.length()); // 0
System.out.println(b.length()); // error; b is not an object

"" ยังคงเป็นสตริงซึ่งหมายความว่าคุณสามารถเรียกวิธีการและรับข้อมูลที่มีความหมายได้ null เป็นตัวแปรว่างเปล่า - ไม่มีสิ่งใดที่แท้จริง


9

มีความแตกต่างที่สำคัญระหว่างสองคนนี้ สตริงว่าง""คือ "สตริงที่ไม่มีอักขระ" มันเป็นสตริงจริงที่มีความยาวที่กำหนดอย่างดี การดำเนินการสตริงมาตรฐานทั้งหมดได้รับการกำหนดอย่างดีในสตริงว่าง - คุณสามารถแปลงเป็นกรณีที่ต่ำกว่าค้นหาดัชนีของตัวละครบางตัวในนั้น ฯลฯ สตริง null nullคือ "ไม่มีสตริงเลย" มันไม่มีความยาวเพราะมันไม่ได้เป็นสตริงเลย การพยายามใช้การดำเนินการสตริงมาตรฐานใด ๆ กับสตริง null จะทำให้เกิดการNullPointerExceptionทำงานแบบรันไทม์


9

นี่a is an Objectแต่b(null)เป็นไม่ได้วัตถุมันเป็นอ้างอิงโมฆะ

System.out.println(a instanceof Object); // true

System.out.println(b instanceof Object); // false

นี่คือคำตอบที่คล้ายกันของฉัน


1
ทั้งสองaและbมีการอ้างอิง aเป็นการอ้างอิงกับวัตถุที่สร้างอินสแตนซ์ bเป็นการอ้างอิงที่ไม่มีวัตถุสร้างอินสแตนซ์ (ดังนั้นคำว่า "การอ้างอิงโมฆะ")
เพียงความคิดเห็นที่ถูกต้องของฉัน

ฉันตอบโต้ -1 ;-) แต่มันจะช่วยชี้แจงคำตอบนี้และหารือเกี่ยวกับความแตกต่างระหว่าง "วัตถุ" กับnullค่าและความแตกต่างระหว่างวัตถุและตัวแปร

@pst ขอบคุณ :) ฉันตอบด้วยใจเพราะนี่คือคำตอบอื่นที่คล้ายกับคำถามนี้stackoverflow.com/questions/4459623//

8

nullหมายความว่าชื่อไม่ได้อ้างอิงถึงวัตถุใด ๆ ที่ยกตัวอย่าง ""หมายถึงสตริงว่าง

นี่กำลังอ้างอิงวัตถุบางอย่างที่เกิดขึ้นจะเป็นสตริงที่ว่างเปล่า bไม่ได้อ้างอิงวัตถุใด ๆ เนื่องจากเป็นโมฆะ


5

ใน Java ชนิดการอ้างอิงที่ได้รับมอบหมายnullมีค่าที่ไม่ทั้งหมด สตริงที่กำหนด""มีค่า: สตริงว่างซึ่งจะกล่าวถึงสตริงที่ไม่มีอักขระในนั้น เมื่อตัวแปรถูกกำหนดnullหมายความว่าไม่มีวัตถุต้นแบบใด ๆ สตริงหรืออื่น ๆ


4

""และnullต่างกัน คนแรกหมายถึงเป็นส่วนหนึ่งของการประกาศตัวแปรสตริงค่าคงที่สตริงถูกสร้างขึ้นในพูลสตริงและหน่วยความจำบางส่วนได้รับการกำหนดเหมือนกัน

แต่เมื่อเราประกาศด้วยค่า nullมันเพิ่งได้รับการยกตัวอย่าง jvm แต่ไม่มีการจัดสรรหน่วยความจำให้ ดังนั้นหากคุณพยายามเข้าถึงวัตถุนี้ด้วยการตรวจสอบด้วย"" - ตัวแปรว่างเปล่ามันไม่สามารถป้องกัน nullpointerexception ได้ โปรดค้นหากรณีการใช้งานด้านล่างหนึ่งรายการ

public class StringCheck {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    String s1 = "siddhartha";
    String s2 = "";
    String s3 = null;

    System.out.println("length s1 ="+s1.length());
    System.out.println("length s2 ="+s2.length());

    //this piece of code will still throw nullpointerexception . 
    if(s3 != ""){
        System.out.println("length s3 ="+s3.length());
    }
}

}


4
String s = "";
s.length();

String s = null;
s.length();

การอ้างอิงถึงสตริงที่ว่างเปล่า""ชี้ไปที่วัตถุในฮีป - ดังนั้นคุณสามารถเรียกใช้เมธอดได้

แต่อ้างอิงชี้ไปที่มีวัตถุไปยังจุดในกองไม่มีและทำให้คุณจะได้รับnullNullPointerException


1

สตริงว่างนั้นแตกต่างจากการอ้างอิงแบบ null ในภาษาการเขียนโปรแกรมเชิงวัตถุการอ้างอิงแบบ null ไปยังชนิดสตริงไม่ได้ชี้ไปที่วัตถุสตริงและจะทำให้เกิดข้อผิดพลาดได้ในการพยายามดำเนินการใด ๆ กับมัน สตริงว่างยังคงเป็นสตริงที่พยายามดำเนินการกับสตริง

จากบทความวิกิพีเดียในสตริงที่ว่างเปล่า


1

String s=null;

สตริงไม่ได้เริ่มต้นสำหรับ null หากการดำเนินการกับสตริงใด ๆ ที่พยายามจะสามารถโยนข้อยกเว้นตัวชี้โมฆะ

String t="null";

มันเป็นตัวอักษรสตริงที่มีสตริงค่า "null" เหมือนกันเช่น t = "xyz" มันจะไม่โยนตัวชี้โมฆะ

String u="";

มันเป็นสตริงว่างเปล่ามันจะไม่โยนตัวชี้โมฆะ


0

สตริงสามารถว่างเปล่าหรือมีnullค่า หากสตริงคือnullมันไม่ได้หมายถึงอะไรในหน่วยความจำ ลองs.length()>0ดู เพราะถ้าสตริงเป็นที่ว่างเปล่าก็ยังคงส่งกลับความยาวของ 0. nullดังนั้นถ้าคุณใส่อะไรที่เหมือนกันแล้วมันจะยังคงดำเนินการวนลูปเพราะมันไม่ได้ลงทะเบียนเป็นสตริง โดยที่ถ้าคุณตรวจสอบความยาวแล้วมันจะออกจากวงมัน


0

แนวคิดนี้สามารถเข้าใจได้ดีขึ้นจากคณิตศาสตร์ คุณเคยลองหารตัวเลข (ไม่เป็นศูนย์) ด้วย 0 โดยใช้เครื่องคิดเลขเช่น 7/0 หรือไม่? คุณจะได้รับผลที่ดูเหมือนว่าสิ่งนี้: undefined, not a number, nullฯลฯ ซึ่งหมายความว่าการดำเนินการเป็นไปไม่ได้ด้วยเหตุผลบางอย่าง (ขอปล่อยให้เหตุผลที่จะกล่าวถึงอีกวัน)

ตอนนี้ทำสิ่งนี้: 0/7 คุณจะได้รับผลลัพธ์ 0 ซึ่งหมายความว่าการดำเนินการเป็นไปได้และสามารถดำเนินการได้ แต่คำตอบของคุณคือ 0 เพราะไม่มีอะไรเหลืออยู่หลังจากการหาร มีเอาต์พุตที่ถูกต้องและเอาต์พุตนั้นเป็นศูนย์

ในตัวอย่างแรกไม่เพียง แต่เป็นเอาต์พุตที่ไม่ถูกต้องการดำเนินการไม่สามารถดำเนินการได้ นี่คือคล้ายกับnullสตริงใน java ตัวอย่างที่สองคล้ายกับemptyสตริง


0

เมื่อคุณเขียน

String a = "";

มันหมายความว่ามีตัวแปร 'a' ของสตริงประเภทที่ชี้ไปที่การอ้างอิงวัตถุในสระว่ายน้ำสตริงที่มีค่า "" เนื่องจากตัวแปรaถือการอ้างอิงวัตถุสตริงที่ถูกต้องวิธีการทั้งหมดของสตริงสามารถนำมาใช้ที่นี่

ในขณะที่คุณเขียน

String b = null;

มันหมายความว่ามีตัวแปรbของประเภทสตริงที่ชี้ไปยังการอ้างอิงที่ไม่รู้จัก และการดำเนินงานใด ๆ NullPointerExceptionในการอ้างอิงที่ไม่รู้จักจะส่งผลให้

ตอนนี้ให้เราประเมินนิพจน์ด้านล่าง

System.out.println(a == b); // false. because a and b both points to different object reference

System.out.println(a.equals(b)); // false, because the values at object reference pointed by a and b do not match.

System.out.println(b.equals(a)); // NullPointerException, because b is pointing to unknown reference and no operation is allowed

0

ในระยะสั้น

  • "" เป็นสตริงว่าง

  • null เป็นที่ว่างเปล่าตัวแปรสตริง


0

ความแตกต่างระหว่างสตริงว่างและว่าง ตัวอย่างเช่นคุณมีตัวแปรชื่อ x ถ้าคุณเขียนใน JS

var x = "";

นี่หมายความว่าคุณได้กำหนดค่าซึ่งเป็นสตริงว่าง (ความยาวคือ 0) อันที่จริงแล้วมันก็เหมือนอะไร แต่ไม่รู้สึกอะไร :) ในทางกลับกัน

var y = null;

นี่หมายความว่าคุณไม่ได้กำหนดค่าให้กับ y ที่พูดอย่างชัดเจนโดยเขียน null ให้กับ y ในเวลาที่ประกาศ ถ้าคุณเขียน y.length; มันจะโยนข้อผิดพลาดซึ่งบ่งชี้ว่าไม่มีการกำหนดค่าให้กับ y และเป็นผลให้ไม่สามารถอ่านความยาวของ y


คำถามสำหรับ Java
Vega


0

"ฉันเรียกมันว่าข้อผิดพลาดพันล้านดอลลาร์ของฉันมันเป็นสิ่งประดิษฐ์ของการอ้างอิงโมฆะในปี 1965" - https://en.wikipedia.org/wiki/Tony_Hoare

ด้วยความเคารพต่อโลกแห่งความเป็นจริงทั้งคู่สามารถสันนิษฐานได้ว่าเหมือนกัน มันเป็นเพียงไวยากรณ์ของภาษาการเขียนโปรแกรมที่สร้างความแตกต่างระหว่างสองอย่างที่คนอื่น ๆ อธิบายไว้ที่นี่ สิ่งนี้จะสร้างค่าใช้จ่ายเช่นเมื่อตรวจสอบ / เปรียบเทียบว่าตัวแปรสตริงมีบางสิ่งหรือไม่คุณต้องตรวจสอบก่อนว่ามันไม่เป็นโมฆะหรือไม่แล้วเปรียบเทียบกับสตริงจริงเช่นการเปรียบเทียบสองรายการ นี่คือพลังการประมวลผลที่สูญเปล่าสำหรับการเปรียบเทียบสตริงทุกครั้ง

Objects.equals () ตรวจสอบ null ก่อนการโทร. equals ()


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.