You can't do it directly, you should provide your own way to check this. Eg.
class MyClass {
Object attr1, attr2, attr3;
public boolean isValid() {
return attr1 != null && attr2 != null && attr3 != null;
}
}
Or make all fields final and initialize them in constructors so that you can be sure that everything is initialized.
Answer from Jack on Stack OverflowYou can't do it directly, you should provide your own way to check this. Eg.
class MyClass {
Object attr1, attr2, attr3;
public boolean isValid() {
return attr1 != null && attr2 != null && attr3 != null;
}
}
Or make all fields final and initialize them in constructors so that you can be sure that everything is initialized.
import org.apache.commons.lang3.ObjectUtils;
if(ObjectUtils.isEmpty(yourObject)){
//your block here
}
The easiest way to check is entity == null. There is no shorter way to do that.
Note that there is a method for this in the standard lib:
Objects.isNull(Object obj)
And another one which is the opposite of the above one:
Objects.nonNull(Object obj)
And there is yet another one which can be used to force a value to be not null, it throws a NullPointerException otherwise:
T Objects.requireNonNull(T obj);
Note: The Objects class was added in Java 7, but the isNull() and nonNull() methods were added only in Java 8.
try this using reflection
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Objects;
public class ObjectsUtils {
public static boolean allNull(Object target) {
return Arrays.stream(target.getClass()
.getDeclaredFields())
.peek(f -> f.setAccessible(true))
.map(f -> getFieldValue(f, target))
.allMatch(Objects::isNull);
}
private static Object getFieldValue(Field field, Object target) {
try {
return field.get(target);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable == null) {
drawable = getRandomDrawable();
}
The equals() method checks for value equality, which means that it compares the contents of two objects. Since null is not an object, this crashes when trying to compare the contents of your object to the contents of null.
The == operator checks for reference equality, which means that it looks whether the two objects are actually the very same object. This does not require the objects to actually exist; two nonexistent objects (null references) are also equal.
Edited Java 8 Solution:
final Drawable drawable =
Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
.orElseGet(() -> getRandomDrawable());
You can declare drawable final in this case.
As Chasmo pointed out, Android doesn't support Java 8 at the moment. So this solution is only possible in other contexts.
Method overloading can make your implementations more efficient and cleaner:
public static boolean isEmpty(Collection obj) {
return obj == null || obj.isEmpty();
}
public static boolean isEmpty(String string) {
return string == null || string.trim().isEmpty();
}
public static boolean isEmpty(Object obj) {
return obj == null || obj.toString().trim().isEmpty();
}
The Collection version is as efficient as possible.
The String version would be more efficient without the trimming. It would be best to trim your strings as soon you see them, long before they reach this call. If you can review the callers and make sure that the strings are always trimmed at their origins, then you can remove .trim() for best performance.
The Object version can be inefficient, depending on the toString implementation of the objects that will be passed to it, and because of the trimming.
I removed the comparison with null from there, because it seems pointless to me. I mean, a class whose toString method says "null" would seem very very odd.
In any case, you don't really want the Object version to be called, at all. Most importantly because it probably won't even work. Take for example an empty Map. Its toString method returns the string {}, which won't match your conditions of emptiness. (For this type you should definitely add isEmpty(Map<?, ?> map) to benefit from its isEmpty method.)
If performance is so critical, then add more overloaded implementations for all other types that you care about, for example:
public static boolean isEmpty(Something obj) {
return obj == null || obj.isEmpty();
}
Finally, especially when something is so important, you definitely want to unit test it, for example:
@Test
public void testEmptyObject() {
assertTrue(isEmpty((Object) null));
assertFalse(isEmpty(new Object()));
}
@Test
public void testEmptyString() {
assertFalse(isEmpty("hello"));
assertTrue(isEmpty(""));
assertTrue(isEmpty(" "));
assertTrue(isEmpty((Object) null));
}
@Test
public void testEmptySet() {
assertFalse(isEmpty(new HashSet<String>(Arrays.asList("hello"))));
assertTrue(isEmpty(new HashSet<String>()));
}
@Test
public void testEmptyMap() {
Map<String, String> map = new HashMap<String, String>();
assertTrue(isEmpty(map));
map.put("hello", "hi");
assertFalse(isEmpty(map));
}
Don't.
I mean. Don't use the same method for all kinds of objects.
This method does not make much sense to me.
This line smells. A lot.
if (obj instanceof Collection)
return ((Collection<?>) obj).size() == 0;
Beware of instanceof operator.
I am sure that whatever it is that you are trying to do here, there are better ways to do it.
Java is a statically typed language, use the static types whenever possible. If you really don't know what type the object have, then I will provide another alternative below.
// is below line expensive?
final String s = String.valueOf(obj).trim();
That depends, on the implementation of the object's toString method.
The implementation of String.valueOf is:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
return s.length() == 0 || s.equalsIgnoreCase("null");
You have already checked for obj == null. The string will only be null when the object's toString method makes it so. And instead of s.length() == 0 you can use s.isEmpty() directly. (Although that is implemented as string length == 0
Do it differently
If possible, have the types of objects you're investigating implement an interface that provides an isEmpty method and let the object decide for itself if it is empty or not.
If that is not possible, you can use a dynamically created map with ways to determine whether or not the object is "empty".
Map<Class<?>, EmptyChecker> map = new HashMap<>();
map.put(String.class, new StringEmptyChecker());
map.put(Point.class, new PointEmptyChecker());
This is a kind of Strategy pattern.
Then to determine if an object is empty:
EmptyChecker checker = map.get(obj.getClass());
checker.isEmpty(obj);
The whole thing is kinda weird though, I can't really see a particular use-case for this kind of method.
You can chain all of those calls via Optional::map. I sort of find this easier to read than if/else, but it might be just me
Optional.ofNullable(person.getClothes())
.map(Clothes::getCountry)
.map(Country::getCapital)
.ifPresent(...)
These "cascade" null-checks are really paranoid and defensive programming. I'd start with a question, isn't better to make it fail fast or validate the input right before it's store into such a data structure?
Now to the question. As you have used nested the null-check, you can do the similar with Optional<T> and a method Optional::map which allows you to get a better control:
Optional.ofNullable(person.getClothes())
.map(clothes -> clothes.getCountry())
.map(country -> country.getCapital())
.orElse(..) // or throw an exception.. or use ifPresent(...)
Your solution is very smart. The problem I see is the fact that you don't know why you got a null? Was it because the house had no rooms? Was it becuase the town had no houses? Was it because the country had no towns? Was it because there was a null in the 0 position of the collection because of an error even when there are houses in positions 1 and greater?
If you make extensibe use of the NonPE class, you will have serious debugging problems. I think it is better to know where exactly the chain is broken than to silently get a null that could be hiding a deeper error.
Also this violates the Law of Demeter: country.getTown().getHouses().get(0).getLivingRoom(). More often than not, violating some good principle makes you have to implement unorthodox solutions to solve the problem caused by violating such principle.
My recommendation is that you use it with caution and try solve the design flaw that makes you have to incur in the train wreck antipattern (so you don't have to use NonPE everywhere). Otherwise you may have bugs that will be hard to detect.
The idea is fine, really good in fact. Since Java 8 the Optional types exist, a detailed explanation can be found at Java Optional type. A example with what you posted is
Optional.ofNullable(country)
.map(Country::getTown)
.map(Town::Houses);
And further on.