1

Is it possible to wrap following code in a reusable function?

EDIT: this is just an example, I want a working solution for ALL recursion depths

what I want is that following code is generated:

if (MyObject o == null || 
    o.getSubObject() == null ||
    o..getSubObject().getSubSubObject() == null /*|| 
    ... */)
    return defaultValue;
return o.getSubObject().getSubObject()/*...*/.getDesiredValue();

by calling something like

Object defaultValue = null;
Object result = NullSafeCall(o.getSubObject().getSubObject()/*...*/.getDesiredValue(), defaultValue);

The seond code block is just an idea, I don't care how it looks like, all I want is that I, if desired, can avoid all the null checks before calling a deeper function...

Injection could do this propably, but is there no other/easier solution? Never looked at injection before yet...

EDIT2: example in another language: http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator

1
  • I'm interested in every solution... the reason this question came up is an android project though... Commented Jul 25, 2013 at 12:29

5 Answers 5

1

Not really, any code you would write this way would look horrible and/or use very slow reflection. Unless you use an actual Java preprocessor that can understand and change the code you've written.

A better (but associated with quite a bit of refactoring) approach would be to make sure that the values in question cannot possibly be null. For example, you could modify the individual accessors (getSubObject(), getDesiredValue()) to never return null in the first place: make them return default values. The accessors on the default values return default values in turn.

Sign up to request clarification or add additional context in comments.

4 Comments

that's one solution, I know... actually, I don't care if these functions returns null, all I want is a default (maybe even null) value to be the result, if ANY object (no matter which level) is null... to avoid the NullPointerException... i just thought there may be a, like you said, for example preprocessor solution or something else... and in my case, I'm accessing an instance of an abstract class, which only can be created at a specific point... and before this point, I don't want to create an empty instance for no reason...
Something like this: groovy.codehaus.org/Operators#Operators-SafeNavigationOperator Unfortunately that's a different language.
BTW found a blog post that proposed this for Java7 - apparently it didn't get in. blog.joda.org/2009/01/…
I saw this as suggestion for java7 as well, but as far as I read there, it never made it into it... but that's exactly what I want...
1

i would suggest just replace

Object result = NullSafeCall(o.getSubObject().getDesiredValue(), defaultValue);

by the

Object result = (o == null || o.subObject == null) ? defaultVlue : o.getSubObject().getDesiredValue();

Create method only if you can reuse it......

1 Comment

that's just a SPECIFIC solution (making a one-liner out of it)... not reusable... I edited my main post to make more clear what I want
1

Java8 helps to get the closest you'll get to your syntax with decent performance I suspect;

// Evaluate with default 5 if anything returns null.
int result = Optional.eval(5, o, x->x.getSubObject(), x->x.getDesiredValue());

This can be done with this utility class;

class Optional {
    public static <T, Tdef, T1> Tdef eval(Tdef def, T input, Function<T,T1> fn1,
                                          Function<T1, Tdef> fn2)
    {
        if(input == null) return def;
        T1 res1 = fn1.apply(input);
        if(res1 == null) return def;
        return fn2.apply(res1);
    }
}

Sadly, you'll need a separate eval() defined per number of method calls in the chain, so you may want to define a few, but compile time type safe and reusable with just about any calls/types.

1 Comment

that sounds really good and comes close to what I want... sadly, just java 8... thanks for that solution though...
0

You can do something like this

public static Object  NullSafeCall(MyObject o,Object defaultValue){
    if ( o == null || o.getSubObject() == null)
    {
        return defaultValue;
    }
    else 
    {
        return o.getSubObject().getDesiredValue();
    }
}

Now you can call this method as follows

 Object result = NullSafeCall(o, defaultValue);

1 Comment

thanks, I'm aware of this SPECIFIC solution, what I want is a function/Pre compiler or what ever syntax that works with ALL classes and all depths... a reusable solution for all objects...
0

What you want is not possible. It is essential to understand that using this syntax: Object result = NullSafeCall(o.getSubObject().getSubObject() ...); the part of o.getSubObject().getSubObject() will be evaluated before any control passes to the function/method thus throwing the exception.

It is required to have some type of context before executing such code. The closest to this I could think of, can be done using anonymous inner classes like the example below:

// intended to be implemented by an anonymous inner class
interface NullSafeOperation<T> {
    public T executeSafely();
};

// our executor that executes operations safely
public static class NullSafeExecutor<T> {
    public NullSafeExecutor() {}

    public T execute(T defaultValue, NullSafeOperation<T> nso) {
        T result = defaultValue;
        try {
            result = nso.executeSafely();
        } catch(NullPointerException e) {
            // ignore
        }
        return result;
    }

    // utility method to create a new instance and execute in one step
    public static <T> T executeOperation(T defaultValue, NullSafeOperation<T> nso) {
        NullSafeExecutor<T> e = new NullSafeExecutor<T>();
        T result = e.execute(defaultValue, nso);
        return result;
    }
}


public static void main(String[] args) {

    final String aNullString = null;

    String result = NullSafeExecutor.executeOperation("MyDefault", new NullSafeOperation<String>() {
        @Override
        public String executeSafely() {
            // trying to call a method on a null string
            // it will throw NullPointerException but it will be catched by the executor
            return aNullString.trim(); 
        }
    });

    System.out.println("Output = " + result); // prints: Output = MyDefault
}

3 Comments

I'm aware of that this syntax can't work, it only shows what I want... you can change the syntax to NullSafeCall("o.getSubObject().getDesiredValue()", defaultValue);... this works great... I could afterwards parse the string and parse the subfunctions and check all their return values (with reflection)... the code in my question, as stated, just demonstrates what I want...
I understand. I just wanted to point out that if there is no context then such a method is not possible. The solution above provides one: your code is wrapped inside an inner class. Using a string version and reflection as you say provides another context.
you are right... but if the compiler would be able to interpret such a syntax, it would need no context... and your solution is a work around, which would work, but it would not safe me from writing unnecessary code which could be automatically generate... and in this case, using a try/catch around the most outer function call would do the trick as well...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.