Is there any benefit to use methods of Objects.java? [duplicate] - java

This question already has an answer here:
Purpose of Objects.isNull(...) / Objects.nonNull(...)
(1 answer)
Closed 4 years ago.
I examined methods of Objects.java, but i couldn't find too much useful sides of that methods. For Example the code that will work when i use Objects.isNull :
public static boolean isNull(Object obj) {
return obj == null;
}
There are the two ways for checking nullity of two objects :
if(o == null)
if(Objects.isNull(o))
So there are not so many differences between them. Another example the code that will work i use Objects.toString
public static String toString(Object o) {
return String.valueOf(o);
}
When i use it It calls toString of object at background.(With only one difference it writes "null", if the object is null because it uses String.valueOf()
And Objects.equals :
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
It will makes null check in every check(without knowing it is necessary or not.)
Am i wrong? If i am, why should i use that methods and other methods of Objects.java?
EDIT
I did not asked this question only for Objects.isNull and Objects.nonNull, i want to know purpose, usability(except for lambdas also) and benefits of Objects class and its methods. But in javadoc is written that only for Objects.isNull and Objects.nonNull have purpose to use with lambdas(as predicate filter(Objects::isNull)). I want to know others as well.

Objects.isNull(), and the more useful Objects.nonNull(), exist for the purpose of being used in lambda expressions. Objects.toString() was introduced for null safety (as pointed out by #davidxxx), but is also very useful in lambdas.
For example, list.stream().filter(Objects::nonNull).map(Objects::toString) will give you a Stream<String> with the results of calling toString() on all the elements in list that are not null.
Objects.equals() is useful precisely when you know that the objects you're comparing might be null, as it saves you some typing.

You seem to be asking 3 separate questions, so I'll address them separately:
isNull() and its companion nonNull() were added in Java 8 to be used as method references, similarly to Integer.sum() and Boolean.logicalOr(). For example:
// Print only non-null elements
list.stream()
.filter(Objects::nonNull)
.forEach(System.out::println);
I don't see any advantage in calling Objects.toString() over String.valueOf(). Maybe it was included for uniformity with the other null-safe helpers.
If you know the objects are non-null, go ahead and use Object.equals(). Objects.equals() is meant to be used when they might both be null.

In some cases some of these methods don't bring a "great" value and you can suitably ignore them.
1) But as you manipulate classes that miss some checks (check null to prevent NullPointerException) or "optimization" (check first reference equality in equals() for example) , using these Objects methods allow to not be hurt by these and so to
keep your client code robust without writing directly all these checks.
2) Another interesting use is for lambda body as you want to use a method reference
3) At last, it allows to make homogeneous the way to perform these very common processings.
These 3 processing rely on 3 different ways :
String.valueOf(o);
if(o == null){...}
a.equals(b);
While these rely on a single way : utility methods defined in Objects.
Objects.toString(o);
if(Objects.isNull(o)){...}
if(Objects.equals(a, b)){...}

Related

== or equals when comparing final static fields

I've returned back to Java after a little break with C# and I'm already tired of writing stuff like a.equals(b) so I was wondering if is there a way to use the == operator without breaking my program.
Here's my situation:
public static class A {
public final static A STATIC_FIELD = new A(prop1, prop2);
public A method(int param){
return (param > 0.5) ? STATIC_FIELD : new A(prop1, prop2);
}
}
Now, can I replace equals with == in the following snippet since I'm referring to the same object or is it wrong?
....
private bool method(){
A aInstance = getAInstance();
int param = Math.Random();
return aInstance.method(param).equals(A.STATIC_FIELD);
}
....
And what if the STATIC_FIELD in a value taken from an enum?
This depends on what do you want to do.
If you need to check if this is exactly the same object, use the direct comparison. If you need to check if the object wraps the same content (like string or number), then .equals should be used.
Most common errors with these methods seem coming from string comparison, where .equals returns true if the strings have the same content but == only returns true if this is the same instance of string.
You should avoid == (ok, let's agree that you know it :-)), also in relation to singleton instances as you may "forget" later that it is created via singleton. But I will give you a hint. Instead of:
if ((var != null) && (var.equals(A.STATIC_FIELD)))
you may write:
if (A.STATIC_FIELD.equals(var))
just like many people do not realize that to compare strings they may use:
if ("static string".equals(varString))
You may also use java.util.Objects.equals to compare objects without all this checking nulls burden.
no you cant use == instead of equals() becuase when we use == in java we are actually comparing the memory address of the object , so if the method returns STATIC_FIELD then it will work properly as its a static object and the address will be same everywhere.
But when method will return new object of A then the address wont match even if the content is same within the class because the new A(param1, param2) insists JVM to create a new object at a different memory location
== checks if two objects are the same instance. If you want to check if two variables are holding the same instance (as they may well be if you are assigning your variables to class constants), == is fine to use. It also won't error if your variable happens to hold null, so it has that benefit over .equals().
Instances of an enum are always constant, and two different instances will never be equal, so == is fine to use for those too.
If you don't override the equals() method, equals() and == do the same thing, check the equality of the references. You can make the replacement in this case, since method() will return the same reference as A.STATIC_FIELD when it is true. See this answer.

How to avoid write code like "XXX!=null" or "XXX!=null || XXX.isEmpty" [duplicate]

This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
I am writing codes that query the database to get the data. There are some classes that consist of Lists, but sometime the list or other attribute can not be initiated and their value is null, so I need to write list!=null || list.isEmpty or attribute != null, before I can use the attribute.
Unfortunately, it easy to forget it, and I really think it is ugly to do it every time when I operate an attribute. I am going to write some code to explain it.
public class SpotVo {
private Double avg;
private String brief;
private ArrayList<HotelVo> hotels;
private int id;
private ArrayList<byte[]> images;
private AddressVo location;
private String name;
private ArrayList<RestaurantVo> restaurants;
}
As you can see, there are some lists and other attributes in this class, there can all be null or empty, can I do something to avoid it?
The answer depends on whether null has a special meaning. For example for a String field does your application need to distinguish between null and ""? For a Collection-valued field does it need to distinguish between null and an empty collection object?
If the answer is "no", then you could write your "data object" classes to normalize the nulls to the respective "in band" values. You could do this in the getters or the setters or the constructors, depending on exactly how the objects are materialized from the database.
A couple of other things you could do are:
Change the database schema to make the respective columns "not null".
If you are using an ORM or a data binding mechanism, try to configure that (via annotations or whatever) to use the "in band" values instead of null.
The point of turning null into "" or an empty array or collection is that you don't need to treat the "in band" value as a special case ... unless the business logic of your application specifically requires this.
In short, if you stamp out the null values systematically, you don't need to test for them in the business logic.
Note that this approach doesn't always work. The case that annoys me is fetching parameters from an HTTPRequest object in a servlet:
The application potentially has to deal with 4 distinct cases:
parameter not present
parameter present with no value / an empty value
parameter present with a non-empty value
parameter present multiple times.
The parameters are being fetched from a standard API rather than a custom class that could be made to normalize the values according to the webapp's requirements.
The easiest way to solve this is with CollectionUtils.isEmpty.
Returns: true if empty or null
This way you can do it in one line.
When it comes to "attributes", there are design patterns that can help with this. Or, you can use Guava's Optional class. You can read more about it here: What's the point of Guava's Optional class
You can write a function that checks if an object is null and/or if it's a String, is it "". Then simply call that function each time you would need to check all of the conditions. Make it return a boolean so that you can just insert it in the if statements.
boolean check(Object o)
{
if (o != null)
{
if (o instanceof String)
{
if (((String) o).equals(""))
return false;
}
return true;
}
return false;
}
Refer to rcook's suggestion in the comments for a better implementation of this.
I think there's two problems here:
One is that you have to check for null values which I absolutely agree is stupid. The problem is that null is a native to the Java language, so the only way to make it slightly nicer is to use methods like the ones mentioned by Steve P and tieTYT. There is however another way of dealing with null by never using it. Of course you cannot completely avoid it, but at least in your own code you should eliminate all null-references. There are a few great arguments for that which I won't cover here, but you can read Avoiding != null statements for more details.
If you're interested a Java-based language, Scala, have developed this nicely by implementing an Option class that can tell whether a value exists or does not (equal to the null value). Nice blog post about it here: http://jim-mcbeath.blogspot.fr/2008/10/avoiding-nulls.html
Having (mostly) stowed the null-issue away, the next problem will be to check for isEmpty or similar when using collections. This is, as you say, a pain in the arse. But I've actually found that these checks can be largely avoided. It all depends on what you need to do with your collection of course, but in most cases collections are used for traversing or manipulation in some way. Using the foreach-loop in Java will make sure nothing is performed if nothing is in the collection. Neat.
There are some cases where a collection must not be empty. Some of these can be avoided though, by having a good design (for instance one that allows empty lists, ensures that no list are empty etc.), but, for the rest of them there are simply no way around. Ever. But, having eliminated the null-checks, calling a few isEmpty now and then isn't that bad :-)
Hope that helped.

How to prevent null check before equals

I find stuff like this rather annoying and ugly in equals methods:
if (field == null)
{
if (other.field != null)
return false;
}
else if ( ! field.equals(other.field))
return false;
In C# I could've done this:
if( ! Object.Equals(field, other.field))
return false;
Is there something similar in Java, or what is the preferred way to do this kind if thing?
Java 7 offers java.util.Objects.equals.
Use commons-lang:
org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)
Source code:
public static boolean equals(Object object1, Object object2) {
if (object1 == object2) {
return true;
}
if ((object1 == null) || (object2 == null)) {
return false;
}
return object1.equals(object2);
}
From Apache
http://commons.apache.org/lang/
That's about equivalent to what you do in C#
Guava equal which does this :
public static boolean equal(#Nullable Object a, #Nullable Object b) {
return a == b || (a != null && a.equals(b));
}
or null object pattern
Guava also has the somewhat related comparison chain and a load of other goodies.
I would write it this way:
return field != null && other.field != null && field.equals(other.field);
which is not as elegant as the C# code line, but much shorter then the if tree you posted.
I accept all answers technically. Practically I will not use any of them in code I have under control because all provided solutions are working around the core problem: null-values. KEEP YOUR CORE MODEL FREE FROM NULL VALUES, and the question is obsolete in this case.
At system borders like third party libraries one has to deal with null values sometimes. They should converted into meaningful values for the core model. There the given solutions are helpful.
Even if Oracle recommends the equals-Methods to be null-safe, think about that: Once you accept null values your model it is getting fragile. The equals-method will not be the last method where you will check for null. You have to manage null-checks in your method call hierarchy. Methods may not be reusable out of the box anymore. Soon, every parameter will be checked for null.
I saw both sides:
On one side code full of null checks, methods that trust not a single parameter anymore and developers that are afraid to forget a null check.
On the other side code with full expressive statements that make clear assertions to have full functioning objects that can be used without fear of NullPointerExceptions.
As part of the Project Coin, there was a proposal for adding a series of null-safe operators to Java. Sadly, they didn't make it into Java 7, maybe they'll appear in Java 8. Here is the general idea of how they would work
Actually everyone follows there own way to do this and also i would like to introduce groovy here.
There is one way
field == null ? false : true; // So basically it will return true when it is not null.
In groovy there is null safe operator for objects. Lets take an example for class
A {
String name = "test1"
String surName = "test2"
public String returnName() {
return name + surName
}
}
A a = null
a?.name
// Mentioned operator ? will actually check whether a is null or not. then it will invoke name.
Note: i didn't applied semi colon in code as this is not require in groovy.
String.valueOf() will solve some of those problems if the toString is implemented for your classes. It will spit out the toString() answer or "null" if the pointer is null.
Use == operator when you are checking for object references, if both the references refers same object it will return true. Otherwise if you are looking for object content then go with .equals method of objects.
So null means it doesn't have any memory location given in heap. So it can be simply checked with '==' operator.

Is it a bad idea if equals(null) throws NullPointerException instead?

The contract of equals with regards to null, is as follows:
For any non-null reference value x, x.equals(null) should return false.
This is rather peculiar, because if o1 != null and o2 == null, then we have:
o1.equals(o2) // returns false
o2.equals(o1) // throws NullPointerException
The fact that o2.equals(o1) throws NullPointerException is a good thing, because it alerts us of programmer error. And yet, that error would not be catched if for various reasons we just switched it around to o1.equals(o2), which would just "silently fail" instead.
So the questions are:
Why is it a good idea that o1.equals(o2) should return false instead of throwing NullPointerException?
Would it be a bad idea if wherever possible we rewrite the contract so that anyObject.equals(null) always throw NullPointerException instead?
On comparison with Comparable
In contrast, this is what the Comparable contract says:
Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.
If NullPointerException is appropriate for compareTo, why isn't it for equals?
Related questions
Comparable and Comparator contract with regards to null
A purely semantical argument
These are the actual words in the Object.equals(Object obj) documentation:
Indicates whether some other object is "equal to" this one.
And what is an object?
JLS 4.3.1 Objects
An object is a class instance or an array.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
My argument from this angle is really simple.
equals tests whether some other object is "equal to" this
null reference gives no other object for the test
Therefore, equals(null) should throw NullPointerException
To the question of whether this asymmetry is inconsistent, I think not, and I refer you to this ancient Zen kōan:
Ask any man if he's as good as the next man and each will say yes.
Ask any man if he's as good as nobody and each will say no.
Ask nobody if it's as good as any man and you'll never get a reply.
At that moment, the compiler reached enlightenment.
An exception really should be an exceptional situation. A null pointer might not be a programmer error.
You quoted the existing contract. If you decide to go against convention, after all this time, when every Java developer expects equals to return false, you'll be doing something unexpected and unwelcome that will make your class a pariah.
I could't disagree more. I would not rewrite equals to throw an exception all the time. I'd replace any class that did that if I were its client.
Think of how .equals is related to == and .compareTo is related to the comparison operators >, <, >=, <=.
If you're going to argue that using .equals to compare an object to null should throw a NPE, then you'd have to say that this code should throw one as well:
Object o1 = new Object();
Object o2 = null;
boolean b = (o1 == o2); // should throw NPE here!
The difference between o1.equals(o2) and o2.equals(o1) is that in the first case you're comparing something to null, similar to o1 == o2, while in the second case, the equals method is never actually executed so there's no comparison happening at all.
Regarding the .compareTo contract, comparing a non-null object with a null object is like trying do this:
int j = 0;
if(j > null) {
...
}
Obviously this won't compile. You can use auto-unboxing to make it compile, but you get a NPE when you do the comparison, which is consistent with the .compareTo contract:
Integer i = null;
int j = 0;
if(j > i) { // NPE
...
}
Not that this is neccessarily an answer to your question, it is just an example of when I find it useful that the behaviour is how it is now.
private static final String CONSTANT_STRING = "Some value";
String text = getText(); // Whatever getText() might be, possibly returning null.
As it stands I can do.
if (CONSTANT_STRING.equals(text)) {
// do something.
}
And I have no chance of getting a NullPointerException. If it were changed as you suggested, I would be back to having to do:
if (text != null && text.equals(CONSTANT_STRING)) {
// do something.
}
Is this a good enough reason for the behaviour to be as it is?? I don't know, but it is a useful side-effect.
If you take object oriented concepts into account, and consider the whole sender and receiver roles, I'd say that behaviour is convenient. See in the first case you're asking an object if he is equal to nobody. He SHOULD say "NO, I'm not".
In the second case though, you don't have a reference to anyone So you aren't really asking anyone. THIS should throw an exception, the first case shouldn't.
I think it's only asymmetric if you kind of forget about object orientation and treat the expression as a mathematical equality. However, in this paradigm both ends play different roles, so it is to be expected that order matters.
As one final point. A null pointer exception should be raised when there's an error in your code. However, Asking an object if he is nobody, shouldn't be considered a programming flaw. I think it's perfectly ok to ask an object if he isn't null. What if you don't control the source that provides you with the object? and this source sends you null. Would you check if the object is null and only afterwards see if they are equals? Wouldn't it be more intuitive to just compare the two and whatever the second object is the comparison will be carried out without exceptions?
In all honesty, I would be pissed if an equals method within its body returns a null pointer exception on purpose. Equals is meant to be used against any sort of object, so it shouldn't be so picky on what it receives. If an equals method returned npe, the last thing on my mind would be that it did that on purpose. Specially considering it's an unchecked exception. IF you did raise an npe a guy would have to remember to always check for null before calling your method, or even worse, surround the call to equals in a try/catch block (God I hate try/catch blocks) But oh well...
Personally, I'd rather it perform as it does.
The NullPointerException identifies that the problem is in the object against which the equals operation is being performed.
If the NullPointerException was used as you suggest and you tried the (sort of pointless) operation of...
o1.equals(o1) where o1= null...
Is the NullPointerException thrown because your comparison function is screwed or because o1 is null but you didn't realise?
An extreme example, I know, but with current behaviour I feel you can tell easily where the problem lies.
In the first case o1.equals(o2) returns false because o1 is not equal to o2, which is perfectly fine. In the second case, it throws NullPointerException because o2 is null. One cannot call any method on a null. It may be a limitation of programming languages in general, but we have to live with it.
It is also not a good idea to throw NullPointerException you are violating the contract for the equals method and making things more complex than it has to be.
There are many common situations where null is not in any way exceptional, e.g. it may simply represent the (non-exceptional) case where a key has no value, or otherwise stand for “nothing”. Hence, doing x.equals(y) with an unknown y is also quite common, and having to always check for null first would be just wasted effort.
As for why null.equals(y) is different, it is a programming error to call any instance method on a null reference in Java, and therefore worthy of an exception. The ordering of x and y in x.equals(y) should be chosen such that x is known to not be null. I would argue that in almost all cases this reordering can be done based on what is known about the objects beforehand (e.g., from their origin, or by checking against null for other method calls).
Meanwhile if both objects are of unknown “nullness”, then other code almost certainly requires checking at least one of them, or not much can be done with the object without risking the NullPointerException.
And since this is the way it is specified, it is a programming error to break the contract and raise an exception for a null argument to equals. And if you consider the alternative of requiring an exception to be thrown, then every implementation of equals would have to make a special case of it, and every call to equals with any potentially null object would have to check before calling.
It could have been specified differently (i.e., the precondition of equals would require the argument to be non-null), so this is not to say that your argumentation is invalid, but the current specification makes for a simpler and more practical programming language.
Note that the contract is "for any non-null reference x". So the implementation will look like:
if (x != null) {
if (x.equals(null)) {
return false;
}
}
x need not be null to be deemed equal to null because the following definition of equals is possible:
public boolean equals(Object obj) {
// ...
// If someMember is 0 this object is considered as equal to null.
if (this.someMember == 0 and obj == null) {
return true;
}
return false;
}
I think it's about convenience and more importantly consistency - allowing nulls to be part of the comparison avoids having to do a null check and implement the semantics of that each time equals is called. null references are legal in many collection types, so it makes sense they can appear as the right side of the comparison.
Using instance methods for equality, comparison etc., necessarily makes the arrangement asymmetric - a little hassle for the huge gain of polymorphism. When I don't need polymorphism, I sometimes create a symmetric static method with two arguments, MyObject.equals(MyObjecta, MyObject b). This method then checks whether one or both arguments are null references. If I specifically want to exclude null references, then I create an additional method e.g. equalsStrict() or similar, that does a null check before delegating to the other method.
You should return false if the parameter is null.
To show that this is the standard, see 'Objects.equals(Object, Object) from java.util, that performs an assymetric null check on the first parameter only (on which equals(Object) will be called). From the OpenJDK SE 11 source code (SE 1.7 contains exactly the same):
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
This also handles two null values as equal.
This is a tricky question. For backward compatability you can't do so.
Imagine the following scenario
void m (Object o) {
if (one.equals (o)) {}
else if (two.equals (o)) {}
else {}
}
Now with equals returning false else clause will get executed, but not when throwing an exception.
Also null is not really equal to say "2" so it makes perfect sense to return false. Then it is probably better to insist null.equals("b") to return also false :))
But this requirement does make a strange and non symmetric equals relation.

What sort of equality does the Apache Commons ObjectUtils equals method test for?

I have always understood there to be two types of equality in Java,
value equality : uses the .equals() method to test that two objects implement an equivalence relation on non-null object references.
reference equality : uses the == operator to test that two primitive types or memory locations are equal.
The following pages describe these language fundamentals in more detail.
Wikibooks Java Programming : Java Programming/Comparing Objects
xyzws Java EE FAQ : What are the differences between the equality operator and the equals method?
Java Platform API : Javadoc for Object.equals()
Java Language Specification : Equality Operators
What none of these links explicitly specify is what should happen if two null object references are compared for value equality. The implicit assumption is that a NullPointerException should be thrown but this is not what is done by the ObjectUtils.equals() method, which might be considered a best practice utility method.
What worries me is that Apache Commons seems to have effectively introduced a third measure of equality into Java by the back door and that the already confusing state of affairs might have been made greatly more complex. I call it a third measure of equality because it attempts to test for value equality and when that fails it falls back to testing for reference equality. The Apache Commons equality test has many similarities with the value equality and reference equality but is also distinctly different.
Am I right to be concerned and to want to avoid using the ObjectUtils.equals() where ever possible?
Is there an argument for claiming that ObjectUtils.equals() provides a useful union of the other two measures of equality?
Chosen Answer
There doesn't seem to be a consensus opinion on this question but I decided to mark Bozho's as correct because he best drew my attention to what I now see as the greatest problem with null-safe equals checks. We should all be writing fail-fast code that addresses the root cause of why two null objects are being compared for value equality rather than trying to sweep the problem under the carpet.
Here's the code of ObjectUtils.equals(..):
public static boolean equals(Object object1, Object object2) {
if (object1 == object2) {
return true;
}
if ((object1 == null) || (object2 == null)) {
return false;
}
return object1.equals(object2);
}
ObjecUtils docs state clearly that objects passed can be null.
Now on the matter whether true should be returned if you compare two nulls. In my opinion - no, because:
when you compare two objects, you are probably going to do something with them later on. This will lead to a NullPointerException
passing two nulls to compare means that they got from somewhere instead of "real" objects, perhaps due to some problem. In that case comparing them alone is wrong - the program flow should have halted before that.
In a custom library we're using here we have a method called equalOrBothNull() - which differs from the equals method in this utility in the null comparison.
Am I right to be concerned and to want
to avoid using the
ObjectUtils.equals() where ever
possible?
No. What you need to consider equals depends on your requirements. And wanting to consider two nulls equal and any non-null unequal to a null without having to deal with NullPointerExceptions is a very, very common requirement (e.g. when you want to fire value-change events from a setter).
Actually, it's how equals() in general should work, and typically, half of that behvaiour is implemented (the API doc of Object.equals() states "For any non-null reference value x, x.equals(null) should return false.") - that it doesn't work the other way round is mainly due to technical restrictions (the language was designed without multiple dispatch to be simpler).
If you are concerned about this then you could either 1) not use this method 2) write your own to wrap it
public class MyObjectUtils {
public static boolean equals(Object obj1, Object obj2) {
return obj1 != null && obj2 != null && ObjectUtils.equals(obj1, obj2);
}
}
To me it seems weird to allow for null to be equals to null, but this doesn't seem like a large problem. For the most part, I wouldn't expect my application to even get into code paths that involve equality tests if one or more objects are null.

Categories

Resources