Null có phải là một đối tượng không?


119

Null có phải là một Objecttrong Java không?


41
Không, không phải vậy, và đối với những người thắc mắc tại sao lại đặt câu hỏi như vậy, có những ngôn ngữ mà null thực sự là một đối tượng giống như bất kỳ, ví dụ như Ruby.
JRL

7
Trong Scala, rất tỉ mỉ về các loại, có một loại Null( thực tế là một đặc điểm ) có một trường hợp duy nhất null.
Carl Smotricz

1
@JRL: Chỉ vì tò mò, tôi tự hỏi điều đó ảnh hưởng như thế nào đến cách JRuby hoạt động ... (Tôi không đủ quen với mức độ triển khai đó để biết chắc chắn.)
Benjamin Oakes

Để thêm vào @ bình luận JRL của - tương đương thô Ruby để nullnil, đó là một thể hiện của NilClass
Eliot Sykes

Hoặc javascript, trong đó null instanceof Objectsai nhưng typeof(null)trả về 'object'. Nó có phải là một đối tượng trong trường hợp đó? Ai biết.
Don Hatch

Câu trả lời:


166

Nếu null là một Đối tượng, nó sẽ hỗ trợ các phương thức java.lang.Objectnhư equals(). Tuy nhiên, đây không phải là trường hợp - bất kỳ lệnh gọi phương thức nào trên giá trị rỗng đều dẫn đến a NullPointerException.

Và đây là những gì Đặc tả ngôn ngữ Java phải nói về chủ đề này:

Ngoài ra còn có một kiểu null đặc biệt, kiểu của biểu thức null, không có tên. Vì kiểu null không có tên, nên không thể khai báo một biến kiểu null hoặc ép kiểu null. Tham chiếu null là giá trị duy nhất có thể có của một biểu thức kiểu null. Tham chiếu null luôn có thể được chuyển thành bất kỳ loại tham chiếu nào. Trong thực tế, lập trình viên có thể bỏ qua kiểu null và chỉ giả vờ rằng null chỉ là một ký tự đặc biệt có thể thuộc bất kỳ kiểu tham chiếu nào.

Tôi nghĩ rằng điều này có thể được đun sôi thành "null là đặc biệt".


1
Vì vậy, một đối tượng trong Java chỉ là một đối tượng nếu nó bằng hoặc các lớp con java.lang.Object. Thực tế - có. Bạn không thể tạo một lớp học mà không phải là một lớp con của java.lang.Object, nhưng tôi chưa bao giờ nghĩ về nó từ một quan điểm triết học hơn về quan điểm
Andreas Dolk

Tò mò, của tất cả mọi thứ, doc API choNullPointerException có đề cập đến một » nullđối tượng«... :) Nhưng sau đó, nó cũng là okay để nói về»rỗng con trỏ« ...
Lumi

Bạn đã nói: "Tham chiếu null luôn có thể được chuyển thành bất kỳ loại tham chiếu nào". Vì vậy, chúng ta có thể trả về null (đánh máy-nếu được phép) trong một phương thức có kiểu tham chiếu đối tượng (return) không?
Srichakradhar

1
@Srichakradhar: vâng, chúng tôi có thể! Bạn có thể tìm hiểu dễ dàng hơn bằng cách thử trong mã so với hỏi tại đây.
Michael Borgwardt

1
"Tham chiếu null là giá trị duy nhất có thể có của một biểu thức kiểu null". Đã đến lúc đọc tài liệu Thông số kỹ thuật. :)
sofs1

32

Theo thông số kỹ thuật của Java , nulllà một kiểu có thể được gán cho một biến đối tượng (như một giá trị như được ghi chú trong nhận xét). Tuy nhiên, bạn không thể khởi tạo hoặc tạo các biến kiểu này, bạn phải sử dụng chữ nullđược cung cấp bởi trình biên dịch.


8
null là một kiểu và một giá trị.
Joachim Sauer

5
Các nulltên là "dụ" các nullloại, rõ ràng.
strager

nullkhông phải là một biến, nó là một chữ: JLS, 3.10.7. The Null Literal
Gerold Broser,

Re " nulllà kiểu có thể được gán ": 1) null(trong mã) là chữ null , không phải kiểu null 2) Kiểu không thể được gán cho các biến trong Java nói chung, xem JLS 4.1: " Có [... ] hai loại giá trị dữ liệu có thể được lưu trữ trong biến [...]: giá trị nguyên thủy (§4.2) và giá trị tham chiếu (§4.3). " Đó là tham chiếu null có thể được gán thông qua nullký tự. ... tiếp theo ...
Gerold Broser

3) đối tượng trong " biến đối tượng ", so với biến lớp, thường không tham chiếu đến kiểu mà là thời gian tồn tại. Khi tham chiếu đến kiểu, nó thường được gọi là biến của kiểu tham chiếu hay gọi tắt là biến tham chiếu (kiểu). Tôi biết 4 kiểu trong API Java hiển thị các biến cá thể / đối tượng (có thể có nhiều hơn): mảng với nólength và các lớp con của java.awt.geom.Point2D.
Gerold Broser

28

Hoàn toàn không: null instanceof Objecttrả về false.


17
Và nó cũng tương thích với tất cả các loại tham chiếu.
Chris Vest


12

Null là thiếu một đối tượng.


Nhưng kiểu null có thể gán cho mọi kiểu tham chiếu.
Tom Hawtin - tackline

Không có "kiểu null"; null là một giá trị cụ thể của các biểu thức không nguyên thủy (tức là các tham chiếu; không có "kiểu tham chiếu" trong Java, theo hiểu biết của tôi).
Tommy McGuire

3
Tommy: JLS 4.1: "Cũng có một kiểu null đặc biệt, kiểu của biểu thức null, không có tên."
Ken


12

JRL đã viết:

Không, không, ...

Thông thường, nó phụ thuộc vào việc bạn nhìn vào nó từ đâu, bạn tin ai hơn.

Theo JLS, đúng là như vậy . Đặc biệt nếu bạn diễn đạt lại câu hỏi thành: “Có phải nullnghĩa đen của loại Objectkhông?”. Ngoài JLS 4.1 được trích dẫn bởi Michael Borgwardt ở trên:

Xem JLS 3.10.7 :

Một ký tự null luôn thuộc loại null.

JLS 4.10 :

Các kiểu con của kiểu T là tất cả các kiểu U sao cho T là siêu kiểu của U và kiểu rỗng.

hoặc JLS 4.10.2 :

Các siêu kiểu trực tiếp của kiểu null là tất cả các kiểu tham chiếu khác với bản thân kiểu null.

[Tôi nhấn mạnh.]

Theo trình biên dịch của Eclipse 2019-09, nó không phải là :

true.toString();  // Cannot invoke toString() on the primitive type boolean
null.toString();  // Cannot invoke toString() on the primitive type null

Theo OpenJDKs 12.0.1, javac nó là :

true.toString();  // error: boolean cannot be dereferenced
null.toString();  // error: <null> cannot be dereferenced

Trong đó dấu ngoặc nhọn ngụ ý rằng đó nulllà một kiểu khác với kiểu nguyên thủy. Và theo JLS 4.1 :

Có hai loại kiểu trong ngôn ngữ lập trình Java: kiểu nguyên thủy (...) và kiểu tham chiếu (...).

nếu nó không phải là một trong những nó là khác.


Claudiu đã viết:

null là loại xấu xí.

Au contraire, nulllà đẹp. Thay vào đó, bạn sẽ đề xuất điều gì làm giá trị mặc định cho biến loại tham chiếu? Một sự kết hợp bit tùy ý? Chào mừng bạn đến với vi phạm quyền truy cập hoặc thậm chí tệ hơn, địa ngục con trỏ!


Joachim Sauer đã viết:

null là một kiểu và một giá trị.

Thực tế có ba mục kết hợp với null (xem thêm JLS 3.10.7 ):

  1. Loại null (không được đặt tên khác) .
  2. Nghĩa null đen .
  3. Giá trị tham chiếu rỗng . (Thường được viết tắt là giá trị null hoặc đơn giản là null .)

(1) Lưu ý rằng, theo JLS 4.10.2 được trích dẫn ở trên, kiểu null sử dụng đa kế thừa không chỉ cho các giao diện mà còn cho các lớp. Điều mà chúng ta đều biết là không thể đối với các lập trình viên ứng dụng.

(2) Chữ null có thể được hình dung như một biến được định nghĩa là:

JVM_global final null_type null = new null_type();

Cũng lưu ý JLS 3.9 :

Một loạt các chuỗi ký tự đôi khi được giả định, không chính xác, là từ khóa:

  • nullkhông phải là một từ khóa, mà là một chữ rỗng ( §3.10.7 ).

Liên quan null instanceof <any type>

Với JLS 4.10.2 trong tâm trí (“ kiểu null là kiểu con của mọi kiểu”) null instanceof <any type>nên được đánh giá theo true, phải không? Ngay từ cái nhìn đầu tiên, có, nhưng JLS 15.20.2 đưa ra câu trả lời sâu sắc:

[...] kết quả của instanceoftoán tử truenếu giá trị của RelationalExpression không phải lànull [...]. Nếu không thì kết quả làfalse .

[Tôi nhấn mạnh.]

Hãy tự hỏi bản thân xem điều gì có ý nghĩa hơn (theo quan điểm của một lập trình viên ứng dụng):

  • Đưa ra falsevà do đó chỉ ra rằng một biểu thức tham chiếu không thuộc loại được hiển thị cho chúng ta, tức là cho biết nó không tham chiếu đến bất kỳ điều gì hữu ích cho chúng ta

  • hoặc đưa ra true, do đó thông báo cho chúng tôi rằng biểu thức đánh giá đến một tham chiếu đặc biệt, tham chiếu null , tham chiếu đến một "đối tượng" mà chúng tôi không biết liệu nó có tồn tại hay không và thuộc loại rỗng đặc biệt không có tên, không được hiển thị với chúng tôi nhưng thông qua nghĩa đen , là một kiểu con của bất kỳ kiểu nào bao gồm đa kế thừa và vẫn bị bỏ qua? Cũng hãy xem xét ví dụ thực tế hơn:

     class Car implements Vehicle {  
     ...
     Vehicle car = null;
     ...
     boolean b = car instanceof Car;  // True? There's not even an instance
     ...                              // which could be of type Car.

Điều này cũng dẫn đến:

Tại sao instanceofkhông phải là một cách thích hợp để nói điều gì đó về nullObject-ness của?

Nó được gọi là instanceofkhông sameorsubtypeof. Điều đó có nghĩa là chúng ta đang so sánh kiểu của một cá thể với một kiểu chứ không phải hai kiểu. Bây giờ nullcó nghĩa là: “Không có trường hợp nào” và nếu không có trường hợp thì không có kiểu của trường hợp. Rõ ràng là so sánh không có gì với một cái gì đó được cho là dẫn đến false.

Hoặc trong một ví dụ "hơn" trong thế giới thực:

  • Tôi cầm trên tay một bức ảnh kích thước thật về một quả táo ( = loại tham chiếu ) với chữ »Big Apple« ( = tên loại tham chiếu ) trên đó.
  • Có một cái bàn ( = đống ) trước mặt tôi.
  • Nếu có một quả táo ( = instance ) trên bàn thì có một sợi dây ( = tham chiếu ) được nối với nó.
  • Tôi cầm đầu kia của sợi dây này trong tay ( = biến tham chiếu ).
  • Tôi vạch quả táo dọc theo dây và so sánh nó với hình ảnh của tôi ( = instanceof ).
  • Nếu quả táo có cùng kích thước hoặc lớn hơn bức tranh thì chữ viết »Big Apple« áp dụng cho nó ( = true ).
  • Nếu nó nhỏ hơn, thì không ( = false ).
  • Nếu không có quả táo trên bàn (= không có trường hợp nào ) và do đó, không có dây nào tồn tại ( = null ) thì cách viết cũng không áp dụng ( = false ). Vì: Không quả táo nào là quả táo to? Không, không phải.


Như Michael tổng kết: "null là đặc biệt".


2
Apple và null? Bạn không sợ kiện cáo sao? :)
Gábor Lipták

9

Không, nó không phải là một phiên bản của Class cũng như Class. Đó là một tham chiếu đến không có gì.

Chỉnh sửa : chưa đọc thông số kỹ thuật nên phần trên có thể không chính xác 100%.


5

Như đã giải thích trong chương 4.1 Các loại kiểu và giá trị của đặc tả ngôn ngữ Java, null là kiểu có một giá trị, tham chiếu null (và được biểu thị bằng chữ null):

Cũng có một kiểu null đặc biệt , kiểu của biểu thức null, không có tên. Vì kiểu null không có tên, nên không thể khai báo một biến kiểu null hoặc ép kiểu null. Tham chiếu null là giá trị duy nhất có thể có của một biểu thức kiểu null. Tham chiếu null luôn có thể được chuyển thành bất kỳ loại tham chiếu nào. Trong thực tế, lập trình viên có thể bỏ qua kiểu null và chỉ giả vờ rằng đó nullchỉ là một chữ đặc biệt có thể thuộc bất kỳ kiểu tham chiếu nào.

Tuy nhiên, bạn có thể muốn đọc về Mẫu đối tượng rỗng (mà tôi không khuyên bạn nên sử dụng). Xem Wiki C2 hoặc Wikipedia để biết thêm về mẫu này.


5

Không. Ngay cả khi nó là nó, nó cũng vô dụng vì nó không có bất kỳ phương thức hoặc trường nào.


4

Không, không phải là một đối tượng vì Null instanceof Object sẽ luôn trả về false cũng như chỉ có một null, không phải một cho mỗi lớp.


3
Trong thực tế, null instanceof <anytype>sẽ trở lại false, quá.
Bombe 12/12/09

4

Theo Java Spec ,

Ngoài ra còn có một ký tự null đặc biệt có thể được sử dụng làm giá trị cho bất kỳ loại tham chiếu nào. null có thể được gán cho bất kỳ biến nào, ngoại trừ các biến thuộc kiểu nguyên thủy. Bạn có thể làm ít điều gì với một giá trị rỗng ngoài việc kiểm tra sự hiện diện của nó. Do đó, null thường được sử dụng trong các chương trình như một điểm đánh dấu để chỉ ra rằng một số đối tượng không khả dụng.


4

Java xử lý các đối tượng thông qua các tham chiếu. Null là một phân tích của OO-ness của Java, vì nó đưa bạn xuống dưới mức OO. Không, nó không phải là một đối tượng mà nó là GIÁ TRỊ của một tham chiếu. Và nó không liên quan gì đến các mô hình đối tượng, nhưng liên quan đến hệ thống ống nước của Java, cho phép các đối tượng.


3

Null là một ví dụ của java.lang.Object ? Không.

Null có phải là một đối tượng không? phụ thuộc vào định nghĩa của " is ".


2
Object foo = null;
System.out.println(foo.toString()); 

Dòng đầu tiên hiển thị nullcó thể được chỉ định để nhập Object, nhưng dòng thứ hai sẽ chứng minh nó chắc chắn không phải là một Objectvà cuối cùng dẫn đến mộtjava.lang.NullPointerException


1

Không, nullkhông phải là một đối tượng. Nó là một kiểu tham chiếu và giá trị của nó không tham chiếu đến bất kỳ đối tượng nào và vì vậy không có đại diện nào nulltrong bộ nhớ.


OP yêu cầu (kiểu) Object, không phải đối tượng ( ví dụ như một kiểu ). Và nếu một rephrases các câu hỏi phù hợp ...
Gerold Broser
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.