Một int có thể là null trong Java?


155

Có thể intnulltrong Java?

Ví dụ:

int data = check(Node root);

if ( data == null ) {
 // do something
} else {
 // do something
}

Mục tiêu của tôi là viết một hàm trả về một int. Said intđược lưu trữ theo chiều cao của một nút và nếu nút đó không có mặt, nó sẽ là null và tôi sẽ cần kiểm tra xem.

Tôi đang làm điều này cho bài tập về nhà nhưng phần cụ thể này không phải là một phần của bài tập về nhà, nó chỉ giúp tôi vượt qua những gì tôi đang làm.

Cảm ơn các ý kiến, nhưng có vẻ như rất ít người thực sự đọc những gì theo mã, tôi đã hỏi làm thế nào khác tôi có thể thực hiện mục tiêu này; thật dễ dàng để tìm ra rằng nó không hoạt động.


1
Đó là lỗi thời gian biên dịch.
MayurB

Câu trả lời:


201

int không thể là null, nhưng Integer có thể . Bạn cần cẩn thận khi unboxing null Integers vì điều này có thể gây ra nhiều nhầm lẫn và gãi đầu!

ví dụ:

int a = object.getA(); // getA returns a null Integer

sẽ cung cấp cho bạn một NullPointerException, mặc dù đối tượng không phải là null!

Để theo dõi câu hỏi của bạn, nếu bạn muốn chỉ ra sự vắng mặt của một giá trị, tôi sẽ điều trajava.util.Optional<Integer>


2
Có nhiều lý do tốt cho sự tồn tại của lớp Integer, vì vậy hãy sử dụng nó khi các nhu cầu hấp dẫn.
Bleek Geek

6
@ h2g2java: Tôi hy vọng bạn không nghĩ rằng việc có thể sử dụng chúng với bộ sưu tập mặc định là hấp dẫn bởi vì đối với những thứ như HashMap <Integer, Integer> thì mức độ lãng phí là rất lớn và không hấp dẫn. Đó là lý do tại sao TIntIntHashMap của Trove, chỉ sử dụng các nguyên hàm, chạy xung quanh vòng tròn HashMap không hấp dẫn <Integer, Integer>.
Cú phápT3rr0r

1
int không thể được kiểm tra null, tuy nhiên, bạn có thể gán null cho int trong Java một cách an toàn bằng cách chuyển nó sang Integer, ví dụ nếu phương thức check (root) có thể trả về null thì bạn có thể chuyển nó thành int một cách an toàn này: int data = (Integer)check(node);
sactiw

@sactiw - Bạn có thể giải thích? Tôi không chắc là tôi hiểu những gì bạn đang nhận được
Brian Agnew

7
@BrianAgnew Hãy để tôi sửa lại những gì tôi đã nói ở đây, tôi hoàn toàn sai, về cơ bản tôi đã không nhận ra rằng int i = (Integer)null;sẽ ném NPE vào thời gian chạy trong khi mở hộp.
sactiw

40

Không. Chỉ tham chiếu đối tượng có thể là null, không phải là nguyên thủy.


3
Điều đáng nói là lớp Integer sẽ phù hợp hơn nếu OP muốn có giá trị null. Hoặc anh ta có thể sử dụng một giá trị âm để biểu thị "không tìm thấy"
Glen

31

Một cách tuyệt vời để tìm hiểu:

public static void main(String args[]) {
    int i = null;
}

Cố gắng biên dịch.


37
Trên thực tế .. OP đã phát hiện ra rằng theo cụm từ cuối cùng trong câu hỏi của mình: thật dễ dàng để nhận ra rằng nó không hoạt động.
BalusC

9
Đối với hậu thế gần 4 năm sau - bit đó đã được chỉnh sửa sau đó.
Matt Luongo

3
nhưng .. Integer ii = null; int i = ii;sẽ biên dịch nhưng ném
NullPulumException

13

Trong Java, int là một kiểu nguyên thủy và nó không được coi là một đối tượng. Chỉ các đối tượng có thể có một giá trị null. Vì vậy, câu trả lời cho câu hỏi của bạn là không, nó không thể là null. Nhưng nó không đơn giản, bởi vì có những đối tượng đại diện cho hầu hết các loại nguyên thủy.

Lớp Integer đại diện cho một giá trị int, nhưng nó có thể chứa một giá trị null. Tùy thuộc vào checkphương thức của bạn , bạn có thể trả về một số nguyên hoặc một số nguyên.

Hành vi này khác với một số ngôn ngữ hướng đối tượng thuần túy hơn như Ruby, trong đó ngay cả những thứ "nguyên thủy" như ints cũng được coi là đối tượng.


8

Cùng với tất cả các câu trả lời ở trên, tôi cũng muốn thêm điểm này.

Đối với các kiểu nguyên thủy, chúng ta có kích thước bộ nhớ cố định tức là đối với int chúng ta có 4 byte và char chúng ta có 2 byte. Và null chỉ được sử dụng cho các đối tượng vì có kích thước bộ nhớ không cố định.

Vì vậy, theo mặc định, chúng tôi có,

   int a=0;

và không

   int a=null;

Tương tự với các kiểu nguyên thủy khác và do đó null chỉ được sử dụng cho các đối tượng và không phải cho các kiểu nguyên thủy.


5

Mã thậm chí sẽ không biên dịch. Chỉ có một đầy đủ Objectcó thể được null, như thế Integer. Đây là một ví dụ cơ bản để hiển thị khi bạn có thể kiểm tra null:

Integer data = check(Node root);

if ( data == null ) {
 // do something
} else {
 // do something
}

Mặt khác, nếu check()được tuyên bố trở lại int, nó không bao giờ có thể nullvà toàn bộ if-elsekhối sau đó là thừa.

int data = check(Node root);

// do something

Các vấn đề về hộp thư tự động không áp dụng ở đây cũng như khi check()được tuyên bố sẽ trả lại int. Nếu nó đã trở lại Integer, thì bạn có thể gặp rủi ro NullPointerExceptionkhi gán nó cho một intthay vì Integer. Việc gán nó là một Integervà sử dụng if-elsekhối sau đó thực sự sẽ là bắt buộc.

Để tìm hiểu thêm về autoboxing, hãy xem hướng dẫn về Mặt trời này .


1
Thật không may nếu "check" trả về một int chứ không phải là Integer, điều này sẽ không hữu ích, bởi vì int (sẽ không null) sẽ tự động được đóng hộp vào Integer.
Paul Tomblin

2
Xin chào, đó chỉ là một ví dụ cơ bản để hiển thị khi bạn có thể kiểm tra null. Mặt khác, nếu kiểm tra được tuyên bố là trả về int, nó không bao giờ có thể là null và toàn bộ khối if là không cần thiết.
BalusC

3

thay vì khai int ibáo như khai báo Integer ithì chúng ta có thể làmi=null;

Integer i;
i=null;

2

Đối tượng số nguyên sẽ là tốt nhất. Nếu bạn phải sử dụng nguyên thủy, bạn có thể sử dụng một giá trị không tồn tại trong trường hợp sử dụng của bạn. Chiều cao tiêu cực không tồn tại cho mọi người, vì vậy

public int getHeight(String name){
    if(map.containsKey(name)){
        return map.get(name);
    }else{
        return -1;
    }
}

1

Không, nhưng int [] có thể.

int[] hayhay = null; //: allowed (int[] is reference type)
int   hayno  = null; //: error   (int   is primitive type)
                     //: Message: incompatible types: 
                     //: <null> cannot be converted to int

0

Như @Glen đã đề cập trong một bình luận, về cơ bản, bạn có hai cách xoay quanh vấn đề này:

  • sử dụng giá trị "ngoài giới hạn". Chẳng hạn, nếu "dữ liệu" không bao giờ có thể âm trong sử dụng bình thường, hãy trả về giá trị âm để cho biết nó không hợp lệ.
  • Sử dụng một số nguyên. Chỉ cần đảm bảo phương thức "kiểm tra" trả về một Số nguyên và bạn gán nó cho một Số nguyên chứ không phải là số nguyên. Bởi vì nếu một "int" được tham gia trên đường đi, quyền anh tự động và unboxing có thể gây ra vấn đề.

0

Kiểm tra null trong phương thức check () của bạn và trả về giá trị không hợp lệ, chẳng hạn như -1 hoặc 0 nếu null. Sau đó, kiểm tra sẽ cho giá trị đó thay vì chuyển null. Đây sẽ là một điều bình thường để làm trong thời gian cũ 'C'.


0

Bất kỳ kiểu dữ liệu Nguyên thủy nào như int, boolean hoặc float, v.v. đều không thể lưu trữ null (bên), vì java đã cung cấp lớp Wrapper để lưu trữ giống như int với Integer, boolean cho Boolean.

Vd: Số nguyên i = null;


0

Một int không phải là null, nó có thể là 0 nếu không được khởi tạo. Nếu bạn muốn một số nguyên có thể là null, bạn cần sử dụng Integer thay vì int. nguyên thủy không có giá trị null. mặc định có int là 0.

Kiểu dữ liệu / Giá trị mặc định (cho các trường)

int ------------------ 0

dài ---------------- 0L

phao ---------------- 0.0f

gấp đôi ------------- 0,0d

char --------------- '\ u0000'

Chuỗi --------------- null

boolean ------------ sai


-2

Vì bạn yêu cầu một cách khác để thực hiện mục tiêu của mình, tôi khuyên bạn nên sử dụng lớp bao bọc:

new Integer(null);

-17

Tôi không phải là chuyên gia, nhưng tôi tin rằng nulltương đương với một int là 0.

Ví dụ: nếu bạn tạo một int[], mỗi vị trí chứa 0trái ngược với null, trừ khi bạn đặt nó thành một thứ khác.

Trong một số tình huống, điều này có thể được sử dụng.


Rất đơn giản, 0 không giống như null.
Dave Goodchild
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.