Safe get value from chain without NPE - java

Does anyone know any solution to safely get value without NPE and without a lot of if statements?
For example, we have: userInfo.getAddressInfo().getCityName(),
how to get cityName without null-checks?
Sometimes, for my pet projects I use something like that:
public static <T> String safeGetValue(Supplier<String> supplier) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return "";
}
Maybe exists better way to do this.
Full example:
import java.util.function.Supplier;
public class ExampleClass {
public static void main(String[] args) {
UserInfoResponse userInfo = new UserInfoResponse();
String value = safeGetValue(() -> userInfo.getAddressInfo().getCityName());
System.out.println(value);
}
public static <T> String safeGetValue(Supplier<String> supplier) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return "";
}
public static <T> String safeGetValue(Supplier<String> supplier, String defaultValue) {
try {
return supplier.get();
} catch (NullPointerException e) {
e.printStackTrace();
}
return defaultValue;
}
public static <T> String safeGetValue(Supplier<String> supplier, Runnable runnable) {
try {
return supplier.get();
} catch (NullPointerException e) {
runnable.run();
}
return "";
}
public static <T> String safeGetValue(Supplier<String> supplier, Runnable runnable, String defaultValue) {
try {
return supplier.get();
} catch (NullPointerException e) {
runnable.run();
}
return defaultValue;
}
}
class UserInfoResponse {
private String firstName;
private UserAddressInfo addressInfo;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public UserAddressInfo getAddressInfo() {
return addressInfo;
}
public void setAddressInfo(UserAddressInfo addressInfo) {
this.addressInfo = addressInfo;
}
}
class UserAddressInfo {
private String cityName;
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}

I'm looking for a solution without if statements.
Ternary statement can't be a good solution too.
Unfortunately, if tests and conditional expressions are the only alternatives to catching NPEs. (But they are better alternatives!)
To me, the real problem is that the nulls are there in the first place. A better idea is to modify the design so that nulls are not returned. If they are not returned by getters, then you don't have to deal with them.
Here are some ways to design your APIs to not return null.
Make it impossible to create domain objects with null field values:
Constructors and setters should check that their arguments are not null, and thrown an exception (e.g. NPE) when called with bogus null arguments.
Fields could be default initialized with non-null values.
Have the getters return non-null values when field values are null. (But see below!)
Have the getters throw an exception when the user gets a field which should not be null has a null value.
Use the Null Object pattern. Create an special instance of each of your domain objects that represents "no object". Ideally, a Null Object should be immutable ... or should throw an exception if you attempt to modify it by accident.
Use Optional<ReferenceType>.
For builtin types / common types:
use "" instead of null for strings
use a zero length array instead of null for arrays
use (immutable) empty collection objects instead of null for collection types
avoid the primitive wrapper types: use the primitive types that cannot be null.
The other way to look at this is that if your API is specified so that a getter shouldn't return a null, then if it does return a null that is a bug. So, if you then write code to turn the nulls into something else (e.g. empty strings) to avoid the pesky NPEs, what you actually doing is hiding the bugs. A better idea is to let the NPE happen, log it, and then crash the application. (Or return a "500 Internal Error" response.)
Fixing a bug is better than hiding a bug.
But (I hear you ask) "What about reliability? It is embarrassing if my code crashes with NPEs!"
Well yes, but an NPE is better than a null workaround that gives incorrect answers to your users ... or writes bad data into your database.
And the conventional way to avoid bugs (e.g. NPEs) showing up in production is extensive automated testing. More / better unit tests. More / better system tests. Beta test releases, pre-production servers, etc.

Using Optional<T> chain you can write following
UserInfoResponse userInfo = new UserInfoResponse();
String value = Optional.ofNullable(userInfo.getAddressInfo())
.map(UserAddressInfo::getCityName)
.orElse(null);
or
String value = Optional.ofNullable(userInfo)
.map(UserInfoResponse::getAddressInfo)
.map(UserAddressInfo::getCityName)
.orElse(null);
or
String value = Optional.ofNullable(userInfo)
.map(ui -> ui.getAddressInfo())
.map(uai -> uai.getCityName())
.orElse(null);

Related

How to write a junit to verify if an exception thrown by the method is caught?

I have below piece of code in my spring boot app, which validates email addresses
class EmailValidation {
public static void validate(List<String> s){
try {
for (String address : s) {
if (s == null || s.indexOf("#") < 0) {
throw new InvalidEmailAddressException("Email address is invalid ");
}
new InternetAddress(s);
}
} catch(AddressException e){
LOGGER.Error("Please validate email addresses");
}
catch(InvalidEmailAddressesException e){
LOGGER.error(e.getMessage());
}
}
class InvalidEmailAddressException extends Exception {
public InvalidEmailAddressException(String message) {
super(message)
}
}
}
I want to write a Junit test which will verify that that InvalidEmailAddressesException was thrown and CAUGHT. How can I do that in JUnit?
In general I agree with the comments that such a test is probably unnecessary.
However, if I wanted to test something like that I would test the two cases separately and that requires a small modification to your code.
Firstly I would construct a method that only throws the exception if there is one.
public static void checkAddresses(List<String> s) throws AddressException, InvalidEmailAddressException {
for (String address : s) {
if (s == null || s.indexOf("#") < 0) {
throw new InvalidEmailAddressException("Email address is invalid ");
}
new InternetAddress(s);
}
}
then I would use it in your code like that:
class EmailValidation {
public static void validate(List<String> s){
try {
checkAddresses(s); // a wrapper method that throws the expected exceptions
} catch(AddressException e){
LOGGER.Error("Please validate email addresses");
}
catch(InvalidEmailAddressesException e){
LOGGER.error(e.getMessage());
}
}
// add checkAddresses here or somewhere appropriately
class InvalidEmailAddressException extends Exception {
public InvalidEmailAddressException(String message) {
super(message)
}
}
}
Then, I would write separate tests for checkAddresses that tests both if an exception is expected or not and separate tests for validate, (possibly with the same input that was given to checkAddresses) that should pass if an exception isn't thrown.
Also, if you would like to verify your logs may be you could try something like that.
Indeed using java Exception for common cause is considered a bad practice, and as #Michael said, Exceptions must be exceptional, because
they break flow control
they are slow (more details here How slow are Java exceptions?)
they do not mix with functional paradigm (where Java is in part going to with the addition of lamda-expressions
However, creating a custom object for wrapping validation data is a good thing and InvalidEmailAddressException can be turned into CheckedEmail:
import java.util.List;
import java.util.stream.Collectors;
public class EmailValidator {
public List<CheckedEmail> validate(List<String> emailAddresses) {
return emailAddresses.stream().map(this::validate).collect(Collectors.toList());
}
public CheckedEmail validate(String emailAddress) {
String[] emailParts = emailAddress.toString().split( "#", 3 );
final boolean valid;
if ( emailParts.length != 2 ) {
valid = false;
} else {
// More validation can go here using one or more regex
valid = true;
}
return new CheckedEmail(emailAddress, valid);
}
public static final class CheckedEmail {
private final String emailAddress;
private final boolean valid;
private CheckedEmail(String emailAddress, boolean valid) {
this.emailAddress = emailAddress;
this.valid = valid;
}
public String getEmailAddress() {
return emailAddress;
}
public boolean isValid() {
return valid;
}
}
}
This in turn can be tested quite easily (and improved with a parameterized test):
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
public class EmailValidatorTest {
private final EmailValidator emailValidator = new EmailValidator();
#Test
public void invalid_email() {
EmailValidator.CheckedEmail checkedEmail = emailValidator.validate("missing.an.at.symbol");
assertThat(checkedEmail.isValid()).isFalse();
}
#Test
public void valid_email() {
EmailValidator.CheckedEmail checkedEmail = emailValidator.validate("at.symbol#present");
assertThat(checkedEmail.isValid()).isTrue();
}
#Test
public void multiple_email_addresses() {
List<String> emailAddresses = Arrays.asList("missing.an.at.symbol", "at.symbol#present");
List<EmailValidator.CheckedEmail> checkedEmails = emailValidator.validate(emailAddresses);
assertThat(checkedEmails)
.extracting(ce -> ce.getEmailAddress() + " " + ce.isValid())
.containsExactly(
"missing.an.at.symbol false",
"at.symbol#present true");
}
}
If somewhere the point is just to log this, then:
List<EmailValidator.CheckedEmail> checkedEmails = emailValidator.validate(emailAddresses);
checkedEmails.stream()
.filter(ce -> !ce.isValid())
.map(ce -> String.format("Email address [%s] is invalid", ce.getEmailAddress()))
.forEach(logger::error);
Hope this helps !
Don't approach testing that way. You should test only the specified behaviour of your code, not its implementation details.
If the method you are testing delegates to a method that throws a checked exception, and the method you are testing does not also declare that it throws that checked exception, the compiler will enforce that the method catches the exception. So in that case a unit test is unnecessary.
If the method you are testing delegates to a method that throws an unchecked exception, consult the specification of the method to determine whether it is acceptable for the method under test to also throw (propagate) that exception. If it is not acceptable for it to propagate the exception, then you should create a test case that causes the the method delegated to to throw that unchecked exception. If the method propagates the exception, the test case will fail. How to do that? That depends on the method being delegated to, but in most cases you will need to use Dependency Injection to supply a mock object that throws the exception.

JavaSpaces - Objects Returning (Both Read / Take) With All Values as Null

I've been trying to set up some JavaSpaces stuff, but the problem I've been having is strange.
Assume this is the object (not using Object in this case, just trying to obfuscate / generalise) I'm trying to place:
import net.jini.core.entry.*;
public class Object implements Entry {
private String stuff;
public Object() {}
public Object ( String s) {
stuff = s;
}
public String getStuff() { return this.stuff; }
}
And this is the write method:
public void simpleWriteObject(Object object)
{
try {
space.write(object, null, 10000);
} catch (Exception e)
{
}
}
(I've tried it with multiple write methods, including a full transaction one that claims it was submitted successfully.)
Now the read is:
public Object readObject()
{
JavaSpace space = getSpace();
Object objectTemplate = new Object();
try {
Object object = (Object) space.read(objectTemplate, null, LONG.TIME);
return object;
} catch (Exception e)
{
System.out.println("An error occurred. Error: " + e);
return null;
}
}
The problem is that a null object doesn't get returned, I get a completely instantiated object with all the values set to null (as if the object is being created using the no arguments constructor).
So in this case, I'd get an object with [stuff = null] in it:
#Test
void takeObjectFromSpace() {
Object object = new Object("HelloWorld");
objectInteration.simpleWriteObject();
System.out.println(objectInteraction.readObject().getStuff());
}
In reality, if there is nothing in the space it should return a full null object, but it doesn't.
Does anyone have any ideas?
(Found the solution to my own question.)
All objects that implement Entry must have all their variables as Public.

LambdaJ: matching on fields of the same object

Can someone get me out of LambdaJ pit I fell into please?
let's assume I have a list of objects of this class:
private class TestObject {
private String A;
private String B;
//gettters and setters
}
Let's say I want to select the objects from the list where A.equals(B)
I tried this:
List<TestObject> theSameList = select(testList, having(on(TestObject.class).getA(), equalTo(on(TestObject.class).getB())));
but this returns an empty list
And this:
List<TestObject> theSameList = select(testList, having(on(TestObject.class).getA().equals(on(TestObject.class).getB())));
but that throws an exception [EDIT: due to known limitations of proxying final classes]
Note, One way of getting around this is to have a method that compares the two fields inside the TestObject, but let's assume I cannot do this for a reason of your choice.
What am I missing?
After poking and fiddling with LambdaJ to match on the fields of the same object, the only solution that is working for me is writing a custom matcher. Here's quick and dirty implementation of one that would do the job:
private Matcher<Object> hasPropertiesEqual(final String propA, final String propB) {
return new TypeSafeMatcher<Object>() {
public void describeTo(final Description description) {
description.appendText("The propeties are not equal");
}
#Override
protected boolean matchesSafely(final Object object) {
Object propAValue, propBValue;
try {
propAValue = PropertyUtils.getProperty(object, propA);
propBValue = PropertyUtils.getProperty(object, propB);
} catch(Exception e) {
return false;
}
return propAValue.equals(propBValue);
}
};
}
The PropertyUtils is the class from org.apache.commons.beanutils
The way to use this matcher:
List<TestObject> theSameList = select(testList, having(on(TestObject.class), hasPropertiesEqual("a", "b")));

A suitable pattern instead of returning nulls

What would be a good pattern to use here?
I donĀ“t want to return nulls, that just does not feel right.
Another thing is, what if I want to return the reason that causes it to null? If caller knows why it is null, it can do some extra things so I want caller knows it and acts that way
Public CustomerDetails getCustomerDetails(){
if(noCustomer){
..log..etc..
return null;
}
if(some other bad weird condition){
..log..etc..
return null;
}
CustomerDetails details= getCustomerDetailsFromSomewhere();
if (details!=null){
return details;
}
else {
..log..etc..
return null;
}
}
I think you have 3 main options:
If null is a valid state I see no problem in returning null
If null is an invalid state you should throw an exception
Or make use of the Null object pattern
If you are using googles Guava libraries you can also use the Optional class.
The more natural way in Java is to throw an exception on an error condition.
public CustomerDetails getCustomerDetails(){
if(noCustomer){
..log..etc..
throw new NoSuchCustomer(customerName);
}
if(some other bad weird condition){
..log..etc..
throw new IllegalStateException("some other bad weird condition occurred");
}
CustomerDetails details= getCustomerDetailsFromSomewhere();
if (details==null)
throw new IllegalStateException("Failed to get customer details for "+ customerName);
return details;
}
The method getCustomerDetailsFromSomewhere() could throw an exception instead of returning null.
If you mean that the null does not explain its state, you can wrapper CustomerDetails with another class that can give more details. For example:
class Feedback()
{
private CustomerDetails result;
private int status;
public static final int STATUS_OK = 0;
public static final int STATUS_NULL = 1;
public static final int STATUS_NO_CUSTOMER = 2;
public static final int STATUS_BAD_CONDITION = 3;
public Feedback(CustomerDetails result, int status)
{
this.result = result;
this.status= status;
}
public CustomerDetails getResult(){return result;}
public int getStatus(){return status;}
}
and change your method with:
Public Feedback getCustomerDetails()
{
if(noCustomer)
{
..log..etc..
return new Feedback(null, Feeback.STATUS_NO_CUSTOMER);
}
if(some other bad weird condition)
{
..log..etc..
return new Feedback(null, Feeback.STATUS_BAD_CONDITION);
}
CustomerDetails details = getCustomerDetailsFromSomewhere();
if(details != null)
{
return new Feedback(details, Feeback.STATUS_OK);
}
else
{
..log..etc..
return new Feedback(null, Feeback.STATUS_NULL);
}
}
Then you can get the status by feedback.getStatus().
Try Guava's Optional. See this article on avoiding null: http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained
Use Google Guava Optional.
This will help.
Many of the cases where programmers use null is to indicate some sort
of absence: perhaps where there might have been a value, there is
none, or one could not be found. For example, Map.get returns null
when no value is found for a key.
Optional is a way of replacing a nullable T reference with a
non-null value. An Optional may either contain a non-null T reference
(in which case we say the reference is "present"), or it may contain
nothing (in which case we say the reference is "absent"). It is never
said to "contain null."
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
You could try;
CustomerDetails details = setDetailsToEmpty();
or some equivalent.
You still have to check, either for null or empty customer details.
If you really don't want null create a special CustomerDetails object
...
public static final CustomerDetails EMPTY_CUSTOMER_DETAILS = new CustomerDetails();
...
public CustomerDetails getCustomerDetails(){
...
if (details!=null){
return details;
}
...
return EMPTY_CUSTOMER_DETAILS;

Java "?" Operator for checking null - What is it? (Not Ternary!)

I was reading an article linked from a slashdot story, and came across this little tidbit:
Take the latest version of Java, which
tries to make null-pointer checking
easier by offering shorthand syntax
for the endless pointer testing. Just
adding a question mark to each method
invocation automatically includes a
test for null pointers, replacing a
rat's nest of if-then statements, such
as:
public String getPostcode(Person person) {
String ans= null;
if (person != null) {
Name nm= person.getName();
if (nm!= null) {
ans= nm.getPostcode();
}
}
return ans
}
With this:
public String getFirstName(Person person) {
return person?.getName()?.getGivenName();
}
I've scoured the internet (okay, I spent at least 15 minutes googling variations on "java question mark") and got nothing. So, my question: is there any official documentation on this? I found that C# has a similar operator (the "??" operator), but I'd like to get the documentation for the language I'm working in. Or, is this just a use of the ternary operator that I've never seen before.
Thanks!
EDIT: Link to the article: http://infoworld.com/d/developer-world/12-programming-mistakes-avoid-292
The original idea comes from groovy. It was proposed for Java 7 as part of Project Coin: https://wiki.openjdk.java.net/display/Coin/2009+Proposals+TOC (Elvis and Other Null-Safe Operators), but hasn't been accepted yet.
The related Elvis operator ?: was proposed to make x ?: y shorthand for x != null ? x : y, especially useful when x is a complex expression.
This syntax does not exist in Java, nor is it slated to be included in any of the upcoming versions that I know of.
[EDIT]
Upon further thought, I figured out that it is actually possible to achieve the same only using standard Java 8 classes:
public String getFirstName(Person person) {
return Optional.ofNullable(person)
.map(Person::getName)
.map(Name::getGivenName)
.orElse(null);
}
In this case, it is even possible to choose a default value (like "<no first name>") instead of null by passing it as parameter of orElse.
[Original Answer]
One way to workaround the lack of "?" operator using Java 8 without the overhead of try-catch (which could also hide a NullPointerException originated elsewhere, as mentioned) is to create a class to "pipe" methods in a Java-8-Stream style.
public class Pipe<T> {
private T object;
private Pipe(T t) {
object = t;
}
public static<T> Pipe<T> of(T t) {
return new Pipe<>(t);
}
public <S> Pipe<S> after(Function<? super T, ? extends S> plumber) {
return new Pipe<>(object == null ? null : plumber.apply(object));
}
public T get() {
return object;
}
public T orElse(T other) {
return object == null ? other : object;
}
}
Then, the given example would become:
public String getFirstName(Person person) {
return Pipe.of(person)
.after(Person::getName)
.after(Name::getGivenName)
.get();
}
Java does not have the exact syntax but as of JDK-8, we have the Optional API with various methods at our disposal. So, the C# version with the use of null conditional operator:
return person?.getName()?.getGivenName();
can be written as follows in Java with the Optional API:
return Optional.ofNullable(person)
.map(e -> e.getName())
.map(e -> e.getGivenName())
.orElse(null);
if any of person, getName or getGivenName is null then null is returned.
There was a proposal for it in Java 7, but it was rejected:
http://tech.puredanger.com/java7/#null
See: https://blogs.oracle.com/darcy/project-coin:-the-final-five-or-so (specifically "Elvis and other null safe operators").
The result is that this feature was considered for Java 7, but was not included.
That's actually Groovy's safe-dereference operator. You can't use it in pure Java (sadly), so that post is simply wrong (or more likely slightly misleading, if it's claiming Groovy to be the "latest version of Java").
As lot of answers mentioned Java language don't have this feature.
It is possible in few scenarios with this compiler plugin, with few limitations
In the example code you mentioned can be written as
public String getFirstName(Person person) {
#NullSafe
String retVal = person.getName().getGivenName();
return retVal;
}
PS: I am author of plugin
It is possible to define util methods which solves this in an almost pretty way with Java 8 lambda.
This is a variation of H-MANs solution but it uses overloaded methods with multiple arguments to handle multiple steps instead of catching NullPointerException.
Even if I think this solution is kind of cool I think I prefer Helder Pereira's seconds one since that doesn't require any util methods.
void example() {
Entry entry = new Entry();
// This is the same as H-MANs solution
Person person = getNullsafe(entry, e -> e.getPerson());
// Get object in several steps
String givenName = getNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.getGivenName());
// Call void methods
doNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.nameIt());
}
/** Return result of call to f1 with o1 if it is non-null, otherwise return null. */
public static <R, T1> R getNullsafe(T1 o1, Function<T1, R> f1) {
if (o1 != null) return f1.apply(o1);
return null;
}
public static <R, T0, T1> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, R> f2) {
return getNullsafe(getNullsafe(o0, f1), f2);
}
public static <R, T0, T1, T2> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Function<T2, R> f3) {
return getNullsafe(getNullsafe(o0, f1, f2), f3);
}
/** Call consumer f1 with o1 if it is non-null, otherwise do nothing. */
public static <T1> void doNullsafe(T1 o1, Consumer<T1> f1) {
if (o1 != null) f1.accept(o1);
}
public static <T0, T1> void doNullsafe(T0 o0, Function<T0, T1> f1, Consumer<T1> f2) {
doNullsafe(getNullsafe(o0, f1), f2);
}
public static <T0, T1, T2> void doNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Consumer<T2> f3) {
doNullsafe(getNullsafe(o0, f1, f2), f3);
}
class Entry {
Person getPerson() { return null; }
}
class Person {
Name getName() { return null; }
}
class Name {
void nameIt() {}
String getGivenName() { return null; }
}
I'm not sure this would even work; if, say, the person reference was null, what would the runtime replace it with? A new Person? That would require the Person to have some default initialization that you'd expect in this case. You may avoid null reference exceptions but you'd still get unpredictable behavior if you didn't plan for these types of setups.
The ?? operator in C# might be best termed the "coalesce" operator; you can chain several expressions and it will return the first that isn't null. Unfortunately, Java doesn't have it. I think the best you could do is use the ternary operator to perform null checks and evaluate an alternative to the entire expression if any member in the chain is null:
return person == null ? ""
: person.getName() == null ? ""
: person.getName().getGivenName();
You could also use try-catch:
try
{
return person.getName().getGivenName();
}
catch(NullReferenceException)
{
return "";
}
There you have it, null-safe invocation in Java 8:
public void someMethod() {
String userName = nullIfAbsent(new Order(), t -> t.getAccount().getUser()
.getName());
}
static <T, R> R nullIfAbsent(T t, Function<T, R> funct) {
try {
return funct.apply(t);
} catch (NullPointerException e) {
return null;
}
}
If someone is looking for an alternative for old java versions, you can try this one I wrote:
/**
* Strong typed Lambda to return NULL or DEFAULT VALUES instead of runtime errors.
* if you override the defaultValue method, if the execution result was null it will be used in place
*
*
* Sample:
*
* It won't throw a NullPointerException but null.
* <pre>
* {#code
* new RuntimeExceptionHandlerLambda<String> () {
* #Override
* public String evaluate() {
* String x = null;
* return x.trim();
* }
* }.get();
* }
* <pre>
*
*
* #author Robson_Farias
*
*/
public abstract class RuntimeExceptionHandlerLambda<T> {
private T result;
private RuntimeException exception;
public abstract T evaluate();
public RuntimeException getException() {
return exception;
}
public boolean hasException() {
return exception != null;
}
public T defaultValue() {
return result;
}
public T get() {
try {
result = evaluate();
} catch (RuntimeException runtimeException) {
exception = runtimeException;
}
return result == null ? defaultValue() : result;
}
}
You can test the code which you have provided and it will give syntax error.So, it is not supported in Java.
Groovy does support it and it was proposed for Java 7 (but never got included).
However, you can use the Optional provided in Java 8. This might help you in achieving something on similar line.
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
Example Code for Optional
STEP-1 : Use this generic method.
public static <T> Optional<T> optionalChaining(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
} catch (NullPointerException e) {
return Optional.empty();
}
}
STEP-2 one example of usage of this method is below
Optional<String> rs = optionalChaining(()-> user.getName("Talha").getLastName());
if(rs.isPresent()) {
}
Done !!
Since Android does not support Lambda Functions unless your installed OS is >= 24, we need to use reflection.
// Example using doIt function with sample classes
public void Test() {
testEntry(new Entry(null));
testEntry(new Entry(new Person(new Name("Bob"))));
}
static void testEntry(Entry entry) {
doIt(doIt(doIt(entry, "getPerson"), "getName"), "getName");
}
// Helper to safely execute function
public static <T,R> R doIt(T obj, String methodName) {
try {
if (obj != null)
return (R)obj.getClass().getDeclaredMethod(methodName).invoke(obj);
} catch (Exception ignore) {
}
return null;
}
// Sample test classes
static class Entry {
Person person;
Entry(Person person) { this.person = person; }
Person getPerson() { return person; }
}
static class Person {
Name name;
Person(Name name) { this.name = name; }
Name getName() { return name; }
}
static class Name {
String name;
Name(String name) { this.name = name; }
String getName() {
System.out.print(" Name:" + name + " ");
return name;
}
}
}
If this is not a performance issue for you, you can write
public String getFirstName(Person person) {
try {
return person.getName().getGivenName();
} catch (NullPointerException ignored) {
return null;
}
}

Categories

Resources