Câu trả lời:
Khi bạn khai báo một biến tham chiếu (tức là một đối tượng), bạn thực sự đang tạo một con trỏ tới một đối tượng. Hãy xem xét đoạn mã sau nơi bạn khai báo một biến kiểu nguyên thủy int
:
int x;
x = 10;
Trong ví dụ này, biến x
là một int
và Java sẽ khởi tạo nó 0
cho bạn. Khi bạn gán cho nó giá trị của 10
dòng thứ hai, giá trị của bạn 10
được ghi vào vị trí bộ nhớ được gọi bởi x
.
Nhưng, khi bạn cố gắng khai báo một loại tham chiếu , một cái gì đó khác nhau xảy ra. Lấy mã sau:
Integer num;
num = new Integer(10);
Dòng đầu tiên khai báo một biến có tên num
, nhưng nó không thực sự chứa giá trị nguyên thủy. Thay vào đó, nó chứa một con trỏ (vì kiểu này Integer
là kiểu tham chiếu). Vì bạn chưa nói phải chỉ đến cái gì, Java đặt nó vào null
, có nghĩa là " Tôi đang chỉ vào không có gì ".
Trong dòng thứ hai, new
từ khóa được sử dụng để khởi tạo (hoặc tạo) một đối tượng kiểu Integer
và biến con trỏ num
được gán cho Integer
đối tượng đó .
Điều NullPointerException
này xảy ra khi bạn khai báo một biến nhưng không tạo ra một đối tượng và gán cho biến đó trước khi cố gắng sử dụng nội dung của biến đó (được gọi là dereferences ). Vì vậy, bạn đang chỉ vào một cái gì đó không thực sự tồn tại.
Dereferences thường xảy ra khi sử dụng .
để truy cập một phương thức hoặc trường hoặc sử dụng [
để lập chỉ mục một mảng.
Nếu bạn cố gắng hủy đăng ký num
TRƯỚC KHI tạo đối tượng bạn nhận được a NullPointerException
. Trong các trường hợp tầm thường nhất, trình biên dịch sẽ nắm bắt được vấn đề và cho bạn biết rằng " num may not have been initialized
," nhưng đôi khi bạn có thể viết mã không trực tiếp tạo đối tượng.
Chẳng hạn, bạn có thể có một phương pháp như sau:
public void doSomething(SomeObject obj) {
//do something to obj
}
Trong trường hợp đó, bạn không tạo đối tượng obj
, mà là giả sử rằng nó đã được tạo trước khi doSomething()
phương thức được gọi. Lưu ý, có thể gọi phương thức như thế này:
doSomething(null);
Trong trường hợp này, obj
là null
. Nếu phương thức được dự định để làm một cái gì đó cho đối tượng truyền vào, thì phù hợp để ném NullPointerException
vì đó là lỗi lập trình viên và lập trình viên sẽ cần thông tin đó cho mục đích gỡ lỗi. Vui lòng bao gồm tên của biến đối tượng trong thông báo ngoại lệ, như
Objects.requireNonNull(a, "a");
Ngoài ra, có thể có trường hợp mục đích của phương thức không chỉ hoạt động trên đối tượng được truyền vào, và do đó, một tham số null có thể được chấp nhận. Trong trường hợp này, bạn sẽ cần kiểm tra tham số null và hành xử khác đi. Bạn cũng nên giải thích điều này trong tài liệu. Ví dụ: doSomething()
có thể được viết là:
/**
* @param obj An optional foo for ____. May be null, in which case
* the result will be ____.
*/
public void doSomething(SomeObject obj) {
if(obj == null) {
//do something
} else {
//do something else
}
}
Cuối cùng, Cách xác định ngoại lệ & nguyên nhân bằng cách sử dụng Stack Trace
Những phương pháp / công cụ nào có thể được sử dụng để xác định nguyên nhân để bạn ngăn chặn ngoại lệ khiến chương trình chấm dứt sớm?
Sonar với findbugs có thể phát hiện NPE. Sonar có thể bắt ngoại lệ con trỏ null do JVM tự động không
int a=b
có thể ném NPE nếu b là một Integer
. Có những trường hợp điều này là khó hiểu để gỡ lỗi.
NullPointerException
các vấn đề trong mã của bạn là sử dụng @Nullable
và @NotNull
chú thích. Câu trả lời sau đây có thêm thông tin về điều này. Mặc dù câu trả lời này là cụ thể về IntelliJ IDE, nhưng nó cũng có thể áp dụng cho các công cụ khác như được hiển thị từ các bình luận. (BTW Tôi không được phép chỉnh sửa câu trả lời này trực tiếp, có lẽ tác giả có thể thêm nó không?)
NullPointerException
s là những ngoại lệ xảy ra khi bạn cố gắng sử dụng một tham chiếu trỏ đến không có vị trí nào trong bộ nhớ (null) như thể nó đang tham chiếu một đối tượng. Gọi một phương thức trên tham chiếu null hoặc cố gắng truy cập vào trường của tham chiếu null sẽ kích hoạt a NullPointerException
. Đây là những cách phổ biến nhất, nhưng các cách khác được liệt kê trên NullPointerException
trang javadoc.
Có lẽ mã ví dụ nhanh nhất tôi có thể đưa ra để minh họa NullPointerException
sẽ là:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
Trên dòng đầu tiên bên trong main
, tôi rõ ràng đặt Object
tham chiếu obj
bằng null
. Điều này có nghĩa là tôi có một tài liệu tham khảo, nhưng nó không trỏ đến bất kỳ đối tượng nào. Sau đó, tôi cố gắng xử lý tham chiếu như thể nó trỏ đến một đối tượng bằng cách gọi một phương thức trên nó. Điều này dẫn đến một NullPointerException
vì không có mã để thực thi tại vị trí mà tham chiếu đang trỏ.
(Đây là một kỹ thuật, nhưng tôi nghĩ rằng nó có đề cập đến: Một tham chiếu trỏ đến null không giống như một con trỏ C trỏ đến một vị trí bộ nhớ không hợp lệ. Một con trỏ null thực sự không chỉ ra bất cứ nơi nào , khác biệt một cách tinh tế chỉ đến một vị trí không hợp lệ.)
null
trước khi sử dụng nó, như thế này . Với các biến cục bộ, trình biên dịch sẽ bắt lỗi này, nhưng trong trường hợp này thì không. Có lẽ điều đó sẽ làm cho một bổ sung hữu ích cho câu trả lời của bạn?
Một nơi tốt để bắt đầu là JavaDocs . Họ có điều này được bảo hiểm:
Ném khi một ứng dụng cố gắng sử dụng null trong trường hợp bắt buộc phải có đối tượng. Bao gồm các:
- Gọi phương thức thể hiện của một đối tượng null.
- Truy cập hoặc sửa đổi trường của một đối tượng null.
- Lấy chiều dài của null như thể nó là một mảng.
- Truy cập hoặc sửa đổi các vị trí của null như thể nó là một mảng.
- Ném null như thể nó là một giá trị Ném được.
Các ứng dụng nên ném các thể hiện của lớp này để chỉ ra việc sử dụng bất hợp pháp đối tượng null khác.
Đây cũng là trường hợp nếu bạn cố gắng sử dụng tham chiếu null với synchronized
, điều đó cũng sẽ ném ngoại lệ này, theo JLS :
SynchronizedStatement: synchronized ( Expression ) Block
- Mặt khác, nếu giá trị của Biểu thức là null, a
NullPointerException
sẽ bị ném.
Vì vậy, bạn có một NullPointerException
. Làm thế nào để bạn sửa chữa nó? Hãy lấy một ví dụ đơn giản mà ném một NullPointerException
:
public class Printer {
private String name;
public void setName(String name) {
this.name = name;
}
public void print() {
printString(name);
}
private void printString(String s) {
System.out.println(s + " (" + s.length() + ")");
}
public static void main(String[] args) {
Printer printer = new Printer();
printer.print();
}
}
Xác định các giá trị null
Bước đầu tiên là xác định chính xác giá trị nào gây ra ngoại lệ . Đối với điều này, chúng ta cần phải làm một số gỡ lỗi. Điều quan trọng là học cách đọc một stacktrace . Điều này sẽ cho bạn thấy nơi ngoại lệ được ném:
Exception in thread "main" java.lang.NullPointerException
at Printer.printString(Printer.java:13)
at Printer.print(Printer.java:9)
at Printer.main(Printer.java:19)
Ở đây, chúng ta thấy rằng ngoại lệ được ném vào dòng 13 (trong printString
phương thức). Nhìn vào dòng và kiểm tra giá trị nào là null bằng cách thêm các câu lệnh ghi nhật ký hoặc sử dụng trình gỡ lỗi . Chúng tôi phát hiện ra rằng nó s
là null và gọilength
phương thức trên nó sẽ ném ngoại lệ. Chúng ta có thể thấy rằng chương trình dừng ném ngoại lệ khi s.length()
bị xóa khỏi phương thức.
Dấu vết nơi những giá trị này đến từ
Tiếp theo kiểm tra xem giá trị này đến từ đâu. Bằng cách theo dõi những người gọi phương thức, chúng ta thấy rằng s
được truyền vào printString(name)
trong print()
phương thức vàthis.name
là null.
Theo dõi nơi các giá trị này nên được đặt
Đặt ở đâu this.name
? Trong setName(String)
phương pháp. Với một số gỡ lỗi khác, chúng ta có thể thấy rằng phương thức này hoàn toàn không được gọi. Nếu phương thức được gọi, hãy đảm bảo kiểm tra thứ tự các phương thức này được gọi và phương thức thiết lập không được gọi sau phương thức in.
Điều này là đủ để cung cấp cho chúng tôi một giải pháp: thêm một cuộc gọi đến printer.setName()
trước khi gọiprinter.print()
.
Biến có thể có giá trị mặc định (và setName
có thể ngăn nó được đặt thành null):
private String name = "";
Hoặc là print
hay printString
phương pháp có thể kiểm tra cho null , ví dụ:
printString((name == null) ? "" : name);
Hoặc bạn có thể thiết kế lớp sao cho name
luôn có giá trị khác null :
public class Printer {
private final String name;
public Printer(String name) {
this.name = Objects.requireNonNull(name);
}
public void print() {
printString(name);
}
private void printString(String s) {
System.out.println(s + " (" + s.length() + ")");
}
public static void main(String[] args) {
Printer printer = new Printer("123");
printer.print();
}
}
Xem thêm:
Nếu bạn đã cố gắng gỡ lỗi mà vẫn không có giải pháp, bạn có thể đăng câu hỏi để được trợ giúp thêm, nhưng hãy đảm bảo bao gồm những gì bạn đã thử cho đến nay. Tối thiểu, bao gồm stacktrace trong câu hỏi và đánh dấu các số dòng quan trọng trong mã. Ngoài ra, hãy thử đơn giản hóa mã trước tiên (xem SSCCE ).
NullPointerException
(NPE)?Như bạn nên biết, các loại Java được chia thành các loại nguyên thủy ( boolean
, int
, vv) và các loại tài liệu tham khảo . Các kiểu tham chiếu trong Java cho phép bạn sử dụng giá trị đặc biệt null
là cách nói "không có đối tượng" của Java.
A NullPointerException
được ném vào thời gian chạy bất cứ khi nào chương trình của bạn cố gắng sử dụng null
như thể nó là một tài liệu tham khảo thực sự. Ví dụ: nếu bạn viết điều này:
public class Test {
public static void main(String[] args) {
String foo = null;
int length = foo.length(); // HERE
}
}
câu lệnh được gắn nhãn "TẠI ĐÂY" sẽ cố gắng chạy length()
phương thức trên một null
tham chiếu và điều này sẽ đưa ra một NullPointerException
.
Có nhiều cách bạn có thể sử dụng null
giá trị sẽ dẫn đến một NullPointerException
. Trên thực tế, những điều duy nhất bạn có thể làm null
mà không gây ra NPE là:
==
hoặc!=
toán tử, hoặc instanceof
.Giả sử rằng tôi biên dịch và chạy chương trình trên:
$ javac Test.java
$ java Test
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:4)
$
Quan sát đầu tiên: quá trình biên dịch thành công! Vấn đề trong chương trình KHÔNG phải là lỗi biên dịch. Nó là một thời gian chạy lỗi . (Một số IDE có thể cảnh báo chương trình của bạn sẽ luôn đưa ra một ngoại lệ ... nhưng javac
trình biên dịch chuẩn không có.)
Quan sát thứ hai: khi tôi chạy chương trình, nó xuất ra hai dòng "gobbledy-gook". SAI LẦM!! Đó không phải là gobbledy-gook. Nó là một stacktrace ... và nó cung cấp thông tin quan trọng sẽ giúp bạn theo dõi lỗi trong mã của mình nếu bạn dành thời gian để đọc nó một cách cẩn thận.
Vì vậy, hãy nhìn vào những gì nó nói:
Exception in thread "main" java.lang.NullPointerException
Dòng đầu tiên của dấu vết ngăn xếp cho bạn biết một số điều:
java.lang.NullPointerException
.NullPointerException
là bất thường về mặt này, bởi vì nó hiếm khi có một thông báo lỗi.Dòng thứ hai là dòng quan trọng nhất trong chẩn đoán NPE.
at Test.main(Test.java:4)
Điều này cho chúng ta biết một số điều:
main
phương thức của Test
lớp.Nếu bạn đếm các dòng trong tệp trên, dòng 4 là dòng mà tôi đã gắn nhãn với nhận xét "TẠI ĐÂY".
Lưu ý rằng trong một ví dụ phức tạp hơn, sẽ có rất nhiều dòng trong theo dõi ngăn xếp NPE. Nhưng bạn có thể chắc chắn rằng dòng thứ hai (dòng "at" đầu tiên) sẽ cho bạn biết NPE được ném 1 ở đâu .
Nói tóm lại, theo dõi ngăn xếp sẽ cho chúng ta biết rõ ràng tuyên bố nào của chương trình đã ném NPE.
1 - Không hoàn toàn đúng. Có những thứ gọi là ngoại lệ lồng nhau ...
Đây là phần cứng. Câu trả lời ngắn gọn là áp dụng suy luận logic vào bằng chứng được cung cấp bởi dấu vết ngăn xếp, mã nguồn và tài liệu API có liên quan.
Trước tiên, hãy minh họa bằng ví dụ đơn giản (ở trên). Chúng tôi bắt đầu bằng cách nhìn vào dòng mà dấu vết ngăn xếp đã nói với chúng tôi là nơi NPE xảy ra:
int length = foo.length(); // HERE
Làm thế nào mà có thể ném một NPE?
Trên thực tế, chỉ có một cách: nó chỉ có thể xảy ra nếu foo
có giá trị null
. Sau đó chúng tôi cố gắng chạy length()
phương thức trênnull
và ... BANG!
Nhưng (tôi nghe bạn nói) nếu NPE bị ném bên trong lệnh length()
gọi thì sao?
Chà, nếu điều đó xảy ra, dấu vết ngăn xếp sẽ khác. Dòng "at" đầu tiên sẽ nói rằng ngoại lệ được ném vào một số dòng trong java.lang.String
lớp và dòng 4 Test.java
sẽ là dòng "at" thứ hai.
Vậy nó null
đến từ đâu? Trong trường hợp này, điều đó là hiển nhiên, và rõ ràng chúng ta cần phải làm gì để khắc phục nó. (Gán một giá trị khác null cho foo
.)
OK, vậy chúng ta hãy thử một ví dụ phức tạp hơn một chút. Điều này sẽ yêu cầu một số suy luận hợp lý .
public class Test {
private static String[] foo = new String[2];
private static int test(String[] bar, int pos) {
return bar[pos].length();
}
public static void main(String[] args) {
int length = test(foo, 1);
}
}
$ javac Test.java
$ java Test
Exception in thread "main" java.lang.NullPointerException
at Test.test(Test.java:6)
at Test.main(Test.java:10)
$
Vì vậy, bây giờ chúng tôi có hai dòng "tại". Cái đầu tiên là cho dòng này:
return args[pos].length();
và cái thứ hai là cho dòng này:
int length = test(foo, 1);
Nhìn vào dòng đầu tiên, làm thế nào mà có thể ném NPE? Có hai cách:
bar
là null
thì bar[pos]
sẽ ném NPE.bar[pos]
là null
sau đó gọi length()
nó sẽ ném NPE.Tiếp theo, chúng ta cần tìm ra kịch bản nào giải thích những gì đang thực sự xảy ra. Chúng ta sẽ bắt đầu bằng cách khám phá cái đầu tiên:
Nơi nào bar
đến từ đâu? Nó là một tham số cho lệnh test
gọi phương thức và nếu chúng ta nhìn vào cách test
gọi, chúng ta có thể thấy rằng nó đến từ foo
biến tĩnh. Ngoài ra, chúng ta có thể thấy rõ rằng chúng ta đã khởi tạo foo
một giá trị khác không. Điều đó là đủ để tạm thời bỏ qua lời giải thích này. (Về lý thuyết, một cái gì đó khác có thể thay đổi foo
thành null
... nhưng điều đó không xảy ra ở đây.)
Vậy còn kịch bản thứ hai của chúng ta thì sao? Vâng, chúng ta có thể thấy đó pos
là 1
, vì vậy điều đó có nghĩa là foo[1]
phải null
. Điều này có thể không?
Quả thực là như vậy! Và đó là vấn đề. Khi chúng tôi khởi tạo như thế này:
private static String[] foo = new String[2];
chúng tôi phân bổ một String[]
với hai yếu tố được khởi tạonull
. Sau đó, chúng tôi đã không thay đổi nội dung của foo
... vì vậy foo[1]
vẫn sẽ như vậy null
.
Giống như bạn đang cố gắng truy cập một đối tượng null
. Xem xét ví dụ dưới đây:
TypeA objA;
Tại thời điểm này, bạn vừa khai báo đối tượng này nhưng không được khởi tạo hoặc khởi tạo . Và bất cứ khi nào bạn cố gắng truy cập bất kỳ tài sản hoặc phương thức nào trong đó, nó sẽ ném NullPointerException
có ý nghĩa.
Xem ví dụ dưới đây là tốt:
String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
Một ngoại lệ con trỏ null được đưa ra khi một ứng dụng cố gắng sử dụng null trong trường hợp bắt buộc phải có một đối tượng. Bao gồm các:
null
đối tượng.null
đối tượng.null
như thể nó là một mảng.null
như thể nó là một mảng.null
như thể nó là một giá trị Ném được.Các ứng dụng nên ném các thể hiện của lớp này để chỉ ra các mục đích sử dụng bất hợp pháp khác của null
đối tượng.
Tham khảo: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPulumException.html
null
làm mục tiêu của một synchronized
khối, 2) sử dụng a null
làm mục tiêu của a switch
và bỏ hộp null
.
Một null
con trỏ là một con trỏ đến hư không. Khi bạn hủy đăng ký một con trỏ p
, bạn nói "đưa cho tôi dữ liệu tại vị trí được lưu trữ trong" p ". Khi nào p
là một null
con trỏ, vị trí được lưu trữ p
là nowhere
, bạn đang nói" đưa cho tôi dữ liệu tại vị trí 'không ở đâu' ". Rõ ràng, nó không thể làm điều này, vì vậy nó ném a null pointer exception
.
Nói chung, đó là vì một cái gì đó đã không được khởi tạo đúng cách.
NULL
được viết như null
trong java. Và đó là một điều nhạy cảm trường hợp.
Rất nhiều lời giải thích đã được trình bày để giải thích nó xảy ra như thế nào và cách khắc phục nó, nhưng bạn cũng nên tuân theo các thực tiễn tốt nhất để tránh NullPointerException
s.
Xem thêm: Một danh sách tốt các thực hành tốt nhất
Tôi sẽ thêm, rất quan trọng, sử dụng tốt công cụ final
sửa đổi.
Sử dụng công cụ sửa đổi "cuối cùng" bất cứ khi nào có thể áp dụng trong Java
Tóm lược:
final
sửa đổi để thực thi khởi tạo tốt.@NotNull
và@Nullable
if("knownObject".equals(unknownObject)
valueOf()
hơn toString()
.StringUtils
phương pháp an toàn null StringUtils.isEmpty(null)
.@Nullable
như được liệt kê ở trên) và cảnh báo về các lỗi tiềm ẩn. Cũng có thể suy ra và tạo các chú thích như vậy (ví dụ IntelliJ có thể làm điều đó) dựa trên cấu trúc mã hiện có.
if (obj==null)
. Nếu nó là null thì bạn cũng nên viết mã để xử lý điều đó.
Trong Java, mọi thứ (không bao gồm các kiểu nguyên thủy) đều ở dạng một lớp.
Nếu bạn muốn sử dụng bất kỳ đối tượng nào thì bạn có hai giai đoạn:
Thí dụ:
Object object;
object = new Object();
Tương tự cho khái niệm mảng:
Item item[] = new Item[5];
item[0] = new Item();
Nếu bạn không đưa ra phần khởi tạo thì NullPointerException
phát sinh.
Một ngoại lệ con trỏ null là một chỉ báo cho thấy bạn đang sử dụng một đối tượng mà không khởi tạo nó.
Ví dụ, bên dưới là một lớp sinh viên sẽ sử dụng nó trong mã của chúng tôi.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Đoạn mã dưới đây cung cấp cho bạn một ngoại lệ con trỏ null.
public class School {
Student student;
public School() {
try {
student.getId();
}
catch(Exception e) {
System.out.println("Null pointer exception");
}
}
}
Bởi vì bạn đang sử dụng student
, nhưng bạn đã quên khởi tạo nó như trong mã chính xác được hiển thị bên dưới:
public class School {
Student student;
public School() {
try {
student = new Student();
student.setId(12);
student.getId();
}
catch(Exception e) {
System.out.println("Null pointer exception");
}
}
}
Trong Java, tất cả các biến bạn khai báo thực sự là "tham chiếu" đến các đối tượng (hoặc nguyên thủy) chứ không phải chính các đối tượng.
Khi bạn cố gắng thực hiện một phương thức đối tượng, tham chiếu sẽ yêu cầu đối tượng sống thực hiện phương thức đó. Nhưng nếu tham chiếu đang tham chiếu NULL (nothing, zero, void, nada) thì không có cách nào phương thức được thực thi. Sau đó, thời gian chạy cho bạn biết điều này bằng cách ném NullPulumException.
Tham chiếu của bạn là "trỏ" đến null, do đó "Null -> Con trỏ".
Đối tượng sống trong không gian bộ nhớ VM và cách duy nhất để truy cập nó là sử dụng các this
tham chiếu. Lấy ví dụ này:
public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
}
Và ở một nơi khác trong mã của bạn:
Some reference = new Some(); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference.setId( 1 ); // Execute setId method, now private var id is 1
System.out.println( reference.getId() ); // Prints 1 to the console
otherReference = reference // Now they both point to the only object.
reference = null; // "reference" now point to null.
// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );
// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...
Đây là một điều quan trọng cần biết - khi không còn tham chiếu đến một đối tượng (trong ví dụ ở trên khi reference
và otherReference
cả hai đều trỏ đến null) thì đối tượng đó là "không thể truy cập được". Không có cách nào chúng ta có thể làm việc với nó, vì vậy đối tượng này đã sẵn sàng để được thu gom rác và đến một lúc nào đó, VM sẽ giải phóng bộ nhớ được sử dụng bởi đối tượng này và sẽ phân bổ một đối tượng khác.
Một lần xuất hiện khác xảy NullPointerException
ra khi người ta khai báo một mảng đối tượng, sau đó ngay lập tức cố gắng để hủy bỏ các yếu tố bên trong nó.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
NPE cụ thể này có thể tránh được nếu thứ tự so sánh bị đảo ngược; cụ thể là sử dụng .equals
trên một đối tượng không null được bảo đảm.
Tất cả các phần tử bên trong một mảng được khởi tạo thành giá trị ban đầu chung của chúng ; đối với bất kỳ loại mảng đối tượng, điều đó có nghĩa là tất cả các phần tử là null
.
Bạn phải khởi tạo các thành phần trong mảng trước khi truy cập hoặc hủy bỏ chúng.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Optional
là trả về null. Các từ khóa là tốt. Biết làm thế nào để bảo vệ chống lại nó là rất quan trọng. Điều này cung cấp một sự xuất hiện phổ biến của nó và cách để giảm thiểu nó.