Apa itu null di Jawa?


252

Apa null?

Apakah nullcontoh sesuatu?

Apa set nullmilik?

Bagaimana itu direpresentasikan dalam memori?


yegor256. Tentang nol dari JLS. "Null Literal. Tipe null memiliki satu nilai, referensi nol, diwakili oleh null literal null, yang dibentuk dari karakter ASCII. Huruf nol selalu dari tipe null." Tentang poin dalam artikel. 'Objek yang Dapat Berubah dan Tidak Lengkap' adalah fitur. 'Slow Failing' adalah kemampuan desain. 'Berpikir Komputer vs. Berpikir Objek' hanyalah dua cara berpikir. 'Ambiguous Semantic' terlalu subyektif. 'Penanganan Kesalahan Ad-hoc' adalah jenis lain dari mengatasi kesalahan. Null adalah literal atau apa pun yang ditentukan dalam JLS sebagai kontras dari tidak menjadi baik atau buruk.
Oleksii Kyslytsyn

Jawaban:


310

Apakah null adalah contoh dari apa pun?

Tidak, tidak ada tipe yang nullmerupakan instanceof.

15.20.2 Jenis Operator Perbandingan instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

Pada saat run time, hasil dari instanceofoperator adalah truejika nilai RelationalExpression tidak nulldan referensi dapat dilemparkan ke ReferenceType tanpa menaikkan a ClassCastException. Kalau tidak hasilnya adalah false.

Ini berarti bahwa untuk semua jenis Edan R, untuk apa pun E o, di mana o == null, o instanceof Rselalu false.


Set apa yang dimiliki 'null'?

JLS 4.1 Jenis-Jenis dan Nilai

Ada juga tipe null khusus , tipe ekspresi null, yang tidak memiliki nama. Karena tipe null tidak memiliki nama, tidak mungkin untuk mendeklarasikan variabel dari tipe null atau untuk melemparkan ke tipe null . The nullreferensi adalah satu-satunya nilai yang mungkin dari sebuah ekspresi dari nol jenis. The nullreferensi selalu bisa dilemparkan untuk semua jenis referensi. Dalam praktiknya, programmer dapat mengabaikan tipe nol dan hanya berpura-pura bahwa nullitu hanyalah sebuah literal khusus yang dapat dari jenis referensi apa pun.


Apa itu null?

Seperti yang dikatakan kutipan JLS di atas, dalam praktiknya Anda bisa berpura-pura bahwa itu "hanya literal khusus yang bisa dari jenis referensi apa pun".

Di Jawa, null == null(ini tidak selalu terjadi dalam bahasa lain). Perhatikan juga bahwa berdasarkan kontrak, properti ini juga memiliki (dari java.lang.Object):

public boolean equals(Object obj)

Untuk nullnilai non- referensi x, x.equals(null)harus return false.

Ini juga merupakan nilai default (untuk variabel yang memilikinya) untuk semua jenis referensi:

JLS 4.12.5 Nilai Awal Variabel

  • Setiap variabel kelas, variabel instan, atau komponen array diinisialisasi dengan nilai default saat dibuat:
    • Untuk semua jenis referensi, nilai standarnya adalah null.

Bagaimana ini digunakan bervariasi. Anda dapat menggunakannya untuk mengaktifkan apa yang disebut inisialisasi malas bidang, di mana bidang akan memiliki nilai awal nullsampai benar-benar digunakan, di mana itu diganti dengan nilai "nyata" (yang mungkin mahal untuk dihitung).

Ada juga kegunaan lain. Mari kita ambil contoh nyata dari java.lang.System:

public static Console console()

Pengembalian : Konsol sistem, jika ada, jika tidak null.

Ini adalah pola penggunaan yang sangat umum: nulldigunakan untuk menunjukkan tidak adanya suatu objek.

Berikut contoh penggunaan lain, kali ini dari java.io.BufferedReader:

public String readLine() throws IOException

Pengembalian : A Stringberisi konten baris, tidak termasuk karakter pemutusan baris, atau nulljika akhir aliran telah tercapai.

Jadi di sini, readLine()akan kembali instanceof Stringuntuk setiap baris, sampai akhirnya mengembalikan nulltanda akhir. Ini memungkinkan Anda memproses setiap baris sebagai berikut:

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

Seseorang dapat merancang API sehingga kondisi penghentian tidak tergantung pada readLine()pengembalian null, tetapi orang dapat melihat bahwa desain ini memiliki manfaat membuat semuanya ringkas. Perhatikan bahwa tidak ada masalah dengan garis kosong, karena garis kosong "" != null.

Mari kita ambil contoh lain, kali ini dari java.util.Map<K,V>:

V get(Object key)

Mengembalikan nilai yang dipetakan kunci yang ditentukan, atau nulljika peta ini tidak mengandung pemetaan untuk kunci tersebut.

Jika peta ini mengizinkan nullnilai, maka nilai balik dari nulltidak selalu menunjukkan bahwa peta tidak mengandung pemetaan untuk kunci; mungkin juga peta secara eksplisit memetakan kunci untuk null. The containsKeyoperasi dapat digunakan untuk membedakan dua kasus ini.

Di sini kita mulai melihat bagaimana penggunaan nulldapat mempersulit hal-hal. Pernyataan pertama mengatakan bahwa jika kunci tidak dipetakan, nulldikembalikan. Pernyataan kedua mengatakan bahwa bahkan jika kunci dipetakan, nullbisa juga dikembalikan.

Sebaliknya, java.util.Hashtablemenjaga hal-hal lebih sederhana dengan tidak mengizinkan nullkunci dan nilai; itu V get(Object key), jika kembali null, jelas berarti bahwa kunci tersebut tidak dipetakan.

Anda dapat membaca seluruh API dan menemukan di mana dan bagaimana nulldigunakan. Ingatlah bahwa itu tidak selalu merupakan contoh praktik terbaik .

Secara umum, nulldigunakan sebagai nilai khusus untuk menandakan:

  • Status tidak diinisialisasi
  • Kondisi penghentian
  • Objek yang tidak ada
  • Nilai yang tidak diketahui

Bagaimana itu direpresentasikan dalam memori?

Di jawa Tidak ada yang menjadi perhatian Anda. Dan sebaiknya tetap seperti itu.


Apakah nullitu hal yang baik?

Ini sekarang batas subyektif. Beberapa orang mengatakan itu nullmenyebabkan banyak kesalahan programmer yang bisa dihindari. Ada yang mengatakan bahwa dalam bahasa yang menangkap NullPointerExceptionseperti Java, ada baiknya menggunakannya karena Anda akan gagal-cepat pada kesalahan programmer. Beberapa orang menghindari nulldengan menggunakan pola objek Null , dll.

Ini adalah topik besar sendiri, jadi sebaiknya didiskusikan sebagai jawaban untuk pertanyaan lain.

Saya akan mengakhiri ini dengan kutipan dari penemu nulldirinya, CAR Hoare (dari quicksort fame):

Saya menyebutnya kesalahan miliaran dolar saya. Itu adalah penemuan nullreferensi pada tahun 1965. Pada waktu itu, saya sedang merancang sistem tipe komprehensif pertama untuk referensi dalam bahasa berorientasi objek (ALGOL W). Tujuan saya adalah untuk memastikan bahwa semua penggunaan referensi harus benar-benar aman, dengan pengecekan dilakukan secara otomatis oleh kompiler. Tetapi saya tidak bisa menahan godaan untuk menaruh nullreferensi, hanya karena itu sangat mudah diimplementasikan. Ini telah menyebabkan kesalahan yang tak terhitung banyaknya, kerentanan, dan crash sistem, yang mungkin telah menyebabkan satu miliar dolar rasa sakit dan kerusakan dalam empat puluh tahun terakhir.

The video presentasi ini lebih dalam; itu adalah arloji yang direkomendasikan.


4
Referensi Null ada di LISP (as NIL) pada tahun 1960, dan mungkin sebelumnya. Tapi saya tidak berpikir Hoare benar - benar mencoba mengklaim penemuan referensi nol dalam kutipan itu.
Stephen C

7
Hoare tidak berusaha mengklaim penemuan referensi nol; dia hanya mengklaim bahwa dia menyediakannya di tempat yang sangat berpengaruh. Ada banyak bahasa, termasuk Jawa, yang jelas mengambil inspirasi dari Algol, dan jika penggunaan referensi nol bahkan sebagian terinspirasi oleh atau disalin dari Algol, Hoare benar dalam mengambil sebagian kesalahan atas biaya ini. Saya merasa, bagaimanapun, bahwa perkiraannya agak rendah. Satu triliun dolar mungkin lebih dekat dengan biaya sebenarnya.
cjs

32

Apakah null adalah contoh dari apa pun?

Tidak. Itu sebabnya null instanceof Xakan kembali falseuntuk semua kelas X. (Jangan tertipu oleh fakta bahwa Anda dapat menetapkan nulluntuk variabel yang jenisnya adalah jenis objek. Sebenarnya, tugas tersebut melibatkan konversi jenis implisit; lihat di bawah.)

Set apa yang dimiliki 'null'?

Ini adalah satu-satunya anggota dari tipe null, di mana tipe null didefinisikan sebagai berikut:

"Ada juga tipe null khusus, tipe ekspresi null, yang tidak memiliki nama. Karena tipe null tidak memiliki nama, tidak mungkin untuk mendeklarasikan variabel dari tipe null atau dilemparkan ke tipe null. referensi adalah satu-satunya nilai yang mungkin dari ekspresi tipe nol. Referensi nol selalu dapat dilemparkan ke jenis referensi apa pun. Dalam praktiknya, pemrogram dapat mengabaikan jenis nol dan hanya berpura-pura bahwa null hanyalah literal khusus yang dapat berupa tipe referensi. " JLS 4.1

Apa itu null?

Lihat di atas. Dalam beberapa konteks, nulldigunakan untuk menunjukkan "tidak ada objek" atau "tidak diketahui" atau "tidak tersedia", tetapi makna ini khusus untuk aplikasi.

Bagaimana itu direpresentasikan dalam memori?

Itu spesifik implementasi, dan Anda tidak akan dapat melihat representasi nulldalam program Java murni. (Tetapi nulldirepresentasikan sebagai nol alamat mesin / penunjuk di sebagian besar jika tidak semua implementasi Java.)


14

Apa itu null?

Ini bukan apa-apa.

Apakah null adalah contoh dari apa pun?

Tidak karena tidak ada apa-apa. Itu tidak bisa menjadi contoh dari hal apa pun.

Set apa yang dimiliki null?

Tidak ada set apa pun

Bagaimana itu direpresentasikan dalam memori?

Jika beberapa referensi menunjuk padanya seperti:

Object o=new Object();

Dalam memori tumpukan beberapa ruang yang ditetapkan untuk objek yang baru dibuat. Dan o akan menunjuk ke ruang yang ditugaskan di memori.

Sekarang o=null;

Ini berarti sekarang tidak akan menunjuk ke ruang memori objek.


1
"Sekarang o = null; Ini berarti sekarang o tidak akan menunjuk ke ruang memori objek." Saya pikir ini adalah cara Pengumpulan Sampah bekerja di JAWA
Hardik Mishra

9

Tidak itu bukan turunan dari apa pun, turunan dari akan selalu salah.



6

Null bukan turunan dari kelas mana pun.

Namun, Anda dapat menetapkan null ke variabel jenis apa pun (objek atau array):

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);

6

Null in Java (tm)

Dalam C dan C ++, "NULL" adalah konstanta yang didefinisikan dalam file header, dengan nilai seperti:

    0

atau:

    0L

atau:

    ((void*)0)

tergantung pada opsi penyusun dan model memori. NULL bukan bagian dari C / C ++ itu sendiri.

Di Java (tm), "null" bukan kata kunci, tetapi literal khusus dari tipe null. Ia dapat dilemparkan ke tipe referensi apa saja, tetapi tidak untuk tipe primitif seperti int atau boolean. Nol literal tidak harus memiliki nilai nol. Dan tidak mungkin untuk menggunakan tipe null atau mendeklarasikan variabel dari tipe ini.


5

Representasi bytecode

Java nullmemiliki dukungan JVM langsung: tiga instruksi digunakan untuk mengimplementasikannya:

  • aconst_null: misalnya untuk mengatur variabel menjadi nullseperti padaObject o = null;
  • ifnulldan ifnonnull: misalnya untuk membandingkan objek ke nulldalamif (o == null)

Bab 6 "Set Instruksi Mesin Virtual Java" kemudian menyebutkan efek dari nullpada instruksi lain: ia melempar NullPointerExceptionbanyak dari mereka.

2.4. "Jenis dan Nilai Referensi" juga menyebutkan nulldalam istilah umum:

Nilai referensi juga dapat berupa referensi nol khusus, referensi ke tanpa objek, yang akan dilambangkan dengan nol. Referensi nol pada awalnya tidak memiliki tipe run-time, tetapi dapat dilemparkan ke tipe apa pun. Nilai default dari tipe referensi adalah nol.


4

nulladalah nilai spesial, ini bukan turunan dari apa pun. Untuk alasan yang jelas itu tidak bisa instanceofapa - apa.


3

nulladalah nilai khusus yang bukan turunan dari kelas mana pun. Ini diilustrasikan oleh program berikut:

public class X {
   void f(Object o)
   { 
      System.out.println(o instanceof String);   // Output is "false"
   }
   public static void main(String[] args) {
      new X().f(null);
   }
}

6
Satu-satunya hal yang ditunjukkan contoh adalah itu nullbukan turunan dari String.
Sasha Chedygov

4
Jika Anda mengubah tanda tangan ke void f(String o), itu akan lebih masuk akal.
Thilo

2

null di Java seperti / mirip dengan nullptr di C ++.

Program dalam C ++:

class Point
{
    private:
       int x;
       int y;
    public:
       Point(int ix, int iy)
       {
           x = ix;
           y = iy;
       }
       void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
    Point* p = new Point(3,5);
    if (p != nullptr)
    {
       p->print();
       p = nullptr;
    }
    else
    {
        std::cout << "p is null" << std::endl;
    }
    return 0;
}

Program yang sama di Jawa:

public class Point {
    private int x;
    private int y;
    public Point(int ix, int iy) {
        x = ix;
        y = iy;
    }
    public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
    public static void main(String[] args) {
        Point p = new Point(3,5);
        if (p != null)
        {
            p.print();
            p = null;
        }
        else
        {
            System.out.println("p is null");
        }
    }
}

Sekarang apakah Anda mengerti dari kode di atas apa yang null di Jawa? Jika tidak maka saya sarankan Anda untuk belajar pointer di C / C ++ dan kemudian Anda akan mengerti.

Perhatikan bahwa dalam C, tidak seperti C ++, nullptr adalah undefined, tetapi NULL digunakan sebagai gantinya, yang juga dapat digunakan dalam C ++, tetapi dalam C ++ nullptr lebih disukai daripada hanya NULL, karena NULL dalam C selalu terkait dengan pointer dan itu itu, jadi di C ++ sufiks "ptr" ditambahkan ke akhir kata, dan juga semua huruf sekarang huruf kecil, tetapi ini kurang penting.

Di Jawa setiap variabel tipe kelas non-primitif selalu merujuk ke objek jenis itu atau diwariskan dan nol adalah referensi objek kelas nol, tetapi bukan null pointer, karena di Jawa tidak ada yang namanya "pointer", tetapi referensi ke kelas objek digunakan sebagai gantinya, dan null di Java terkait dengan referensi objek kelas, jadi Anda juga dapat menyebutnya sebagai "nullref" atau "nullrefobj", tetapi ini panjang, jadi sebut saja "null".

Dalam C ++ Anda dapat menggunakan pointer dan nilai nullptr untuk anggota opsional / variabel, yaitu anggota / variabel yang tidak memiliki nilai dan jika tidak memiliki nilai maka itu sama dengan nullptr, jadi bagaimana null di Jawa dapat digunakan misalnya.


1

Ada dua kategori utama tipe di Jawa: primitif dan referensi . Variabel dideklarasikan dari nilai toko tipe primitif; variabel yang dideklarasikan dari referensi tipe toko referensi.

String x = null;

Dalam hal ini, pernyataan inisialisasi mendeklarasikan variabel "x". "X" menyimpan referensi String. Itu nol di sini. Pertama-tama, null bukan instance objek yang valid, jadi tidak ada memori yang dialokasikan untuk itu. Ini hanyalah nilai yang menunjukkan bahwa referensi objek saat ini tidak merujuk ke suatu objek.


0

Cara yang menarik untuk melihat null di java menurut saya adalah melihatnya sebagai sesuatu yang TIDAK menunjukkan tidak adanya informasi tetapi hanya sebagai nilai literal yang dapat ditugaskan untuk referensi jenis apa pun. Jika Anda memikirkannya jika ini menunjukkan tidak adanya informasi maka untuk a1 == a2 menjadi benar tidak masuk akal (jika mereka berdua diberi nilai nol) karena mereka benar-benar dapat menunjuk ke objek APA PUN (kita cukup tidak tahu objek apa yang seharusnya mereka tunjukkan) ... Ngomong-ngomong null == null mengembalikan true di java. Jika java misalnya akan seperti SQL: 1999 maka null == null akan mengembalikan tidak dikenal (nilai boolean dalam SQL: 1999 dapat mengambil tiga nilai: benar, salah dan tidak dikenal tetapi dalam prakteknya tidak diketahui diimplementasikan sebagai nol dalam sistem nyata) ... http://en.wikipedia.org/wiki/SQL


0

Jawaban singkat dan tepat yang menjawab semua pertanyaan Anda secara resmi dari JLS:

3.10.7. The Null Literal

Tipe nol memiliki satu nilai, referensi nol, diwakili oleh null literal nol, yang dibentuk dari karakter ASCII.

Null literal selalu dari tipe null.

Hanya referensi tipe yang ditugaskan ke null yang dialokasikan. Anda tidak memberikan nilai (objek) apa pun ke referensi. Alokasi tersebut khusus untuk JVM berapa banyak referensi yang akan diambil dan di mana area memori itu akan dialokasikan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.