Trong Java tôi được thông báo rằng khi thực hiện kiểm tra null, người ta nên sử dụng == thay vì .equals (). những lý do cho việc này là gì?
Trong Java tôi được thông báo rằng khi thực hiện kiểm tra null, người ta nên sử dụng == thay vì .equals (). những lý do cho việc này là gì?
Câu trả lời:
Chúng là hai thứ hoàn toàn khác nhau. ==
so sánh tham chiếu đối tượng, nếu có, được chứa bởi một biến. .equals()
kiểm tra xem hai đối tượng có bằng nhau theo hợp đồng của họ không có nghĩa là bình đẳng. Hoàn toàn có thể cho hai trường hợp đối tượng riêng biệt là "bằng nhau" theo hợp đồng của họ. Và sau đó có một chi tiết nhỏ rằng đó equals
là một phương pháp, nếu bạn cố gắng gọi nó trên một null
tham chiếu, bạn sẽ nhận được một NullPointerException
.
Ví dụ:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
public int data
sao
Object
, vâng. Mặc dù vậy, nó bị ghi đè bởi một số lượng lớn các lớp JDK. Nhưng vấn đề không phải là về việc thực hiện, đó là về ngữ nghĩa. (Lưu ý bên lề: JDK7 đã hết hạn.)
nếu bạn gọi .equals()
trên null
bạn sẽ nhận đượcNullPointerException
Vì vậy, luôn luôn nên kiểm tra tính vô hiệu trước khi gọi phương thức khi áp dụng
if(str!=null && str.equals("hi")){
//str contains hi
}
Cũng thấy
if ("hi".equals(str))
.
someObject.equals(null)
sẽ tăng lên NullPointerException
mà không bao giờ nhập phương thức bằng.
Objects.equals(a, b)
Nó sẽ không tăng NullPulumException, nhưng nó vẫn phụ thuộc vào phương thức "bằng" của "a" và "b"
Ngoài câu trả lời được chấp nhận ( https://stackoverflow.com/a/4501084/6276704 ):
Vì Java 1.7, nếu bạn muốn so sánh hai Đối tượng có thể là null, tôi khuyên bạn nên sử dụng hàm này:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Lớp này bao gồm các phương thức tiện ích tĩnh để vận hành trên các đối tượng. Các tiện ích này bao gồm các phương thức không an toàn hoặc không khoan nhượng để tính toán mã băm của một đối tượng, trả về một chuỗi cho một đối tượng và so sánh hai đối tượng.
Từ: 1.7
Trong Java 0 hoặc null là các loại đơn giản và không phải là đối tượng.
Phương thức equals () không được xây dựng cho các loại đơn giản. Các loại đơn giản có thể được khớp với ==.
foo.equals(null)
Điều gì xảy ra nếu foo là null?
Bạn nhận được một NullPulumException.
Theo các nguồn , không có vấn đề gì khi sử dụng để thực hiện phương thức mặc định:
public boolean equals(Object object) {
return this == object;
}
Nhưng bạn không thể chắc chắn về equals
lớp học tùy chỉnh.
equals
chỉ có thể trả về false
hoặc gây ra một NullPointerException
(hoặc một cái gì đó khác nếu equals
phương pháp overriden là vô nghĩa).
Object.equals là null an toàn, tuy nhiên, hãy lưu ý rằng nếu hai đối tượng là null, object.equals sẽ trả về true, vì vậy hãy chắc chắn kiểm tra xem các đối tượng bạn đang so sánh không null (hoặc giữ giá trị null) trước khi sử dụng object.equals cho so sánh.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Đoạn trích trên sẽ trả về bằng nhau!
Vì bằng là một hàm xuất phát từ lớp Object, nên hàm này so sánh các mục của lớp. nếu bạn sử dụng nó với null thì nó sẽ trả về sai vì nguyên nhân nội dung lớp không phải là null. Ngoài ra == so sánh tham chiếu đến một đối tượng.
false
hoặc NullPointerException
(nếu equals
không được ghi đè lên một cái gì đó xấu).
đây là một ví dụ str != null
nhưng str.equals(null)
khi sử dụngorg.json
JSONObject jsonObj = new JSONObject("{field :null}");
Object field = jsonObj.get("field");
System.out.println(field != null); // => true
System.out.println( field.equals(null)); //=> true
System.out.println( field.getClass()); // => org.json.JSONObject$Null
EDIT:
đây là lớp org.json.JSONObject $ Null :
/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
* undefined.
*/
private static final class Null {
/**
* A Null object is equal to the null value and to itself.
*
* @param object
* An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or
* null.
*/
@Override
public boolean equals(Object object) {
return object == null || object == this;
}
}
field.equals(null)
trả về đúng sự thật. Điều này phá vỡ hành vi Java thông thường và do đó gây nhầm lẫn. Nó chỉ nên làm việc cho field.equals("null")
, ít nhất là theo quan điểm của tôi. Tôi không biết tại sao các nhà phát triển thư viện nghĩ rằng điều này sẽ tốt để hỗ trợ.
str != null
và str.equals(null)
trở lại true
khi sử dụng org.json ."?
jsonObject
chứa "trường" đó là lý do tại sao field
không phải là null, nó có một tham chiếu chứa json.org.JSONObject$Null
đối tượng
Null
thích null
và sẽ sử dụng "null"
thay thế. Nhưng tôi đoán họ đã làm điều đó để tránh yêu cầu String. Nhưng ngay cả với lib đó, field.equals(null)
vẫn là gần như luôn luôn là một vấn đề: P.
Vì vậy, tôi không bao giờ bị nhầm lẫn và tránh các vấn đề với giải pháp này:
if(str.trim().length() <=0 ) {
// is null !
}
""
có độ dài 0) là một cái gì đó hoàn toàn khác với một null
tham chiếu (tức là không có chuỗi).
Mã của bạn vi phạm luật của Demeter. Đó là lý do tại sao nó tốt hơn để cấu trúc lại thiết kế. Như một giải pháp thay thế, bạn có thể sử dụng Tùy chọn
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
ở trên là để kiểm tra phân cấp của một đối tượng để chỉ cần sử dụng
Optional.ofNullable(object1)
nếu bạn chỉ có một đối tượng để kiểm tra
Hi vọng điêu nay co ich !!!!
Bạn luôn có thể làm
if (str == null || str.equals(null))
Điều này trước tiên sẽ kiểm tra tham chiếu đối tượng và sau đó kiểm tra chính đối tượng cung cấp tham chiếu không null.
x.equals(null)
.
equals()
và xem. Khi bạn thử nó sẽ ngay lập tức trở nên rõ ràng