I have two function calls for Employee and Address DAO class where I check if the employee name or address is already in used
For making it generic to check and throw exception I have created the following generic function
checkOrElseThrow in CommonUtil.java
public static <R, C, T extends Throwable> R checkOrElseThrow(R rtn, C chk, Supplier<? extends T> ex) throws T
{
if (chk != null)
{
throw ex.get();
}
return rtn;
}
and the above generic function is been called in EmployeeDAO.java and AddressDAO.java like as shown below
checkAndReturnEmployee in EmployeeDAO.java
public Employee checkAndReturnEmployee(Employee employee) {
return checkOrElseThrow(
employee,
employee.getAddressName(),
() -> new EntityNotFoundException("Employee already in use for another address"));
}
checkAndReturnAddress in AddressDAO.java
public Address checkAndReturnAddress(Address address) {
return checkOrElseThrow(
address,
address.getEmployeeName(),
() -> new EntityNotFoundException("Address already in use for another address"));
}
Question
My solution is working fine, but I would like to know if there is any other better way to rewrite the generic function (checkOrElseThrow) which I have written
The best way to write this is to not.
public Employee checkAndReturnEmployee(Employee employee) {
if (employee.getAddressName() == null) {
throw new EntityNotFoundException("Employee already in use for another address"));
}
return employee;
}
The code above is just as short, but far more readable. It's clearer what the condition is, and what happens when it is not met.
Your custom function only serves to attempt to create a new syntax for Java, one that other people will not understand, and you may soon forget also.
Since the question was more around the generic implementation, you could modify your existing implementation to make use of a Predicate to test out any criteria and work it out as:
public <R, T extends Throwable> R checkOrElseThrow(R returnValue, Predicate<R> successCriteria,
Supplier<? extends T> ex) throws T {
if (successCriteria.test(returnValue)) {
return returnValue;
}
throw ex.get();
}
and further invoke this in corresponding places as:
public Employee checkAndReturnEmployee(Employee employee) throws EntityNotFoundException {
return checkOrElseThrow(employee, emp -> emp.getAddressName() != null,
() -> new EntityNotFoundException("Employee already in use for another address"));
}
public Address checkAndReturnAddress(Address address) throws EntityNotFoundException {
return checkOrElseThrow(address, add -> add.getEmployeeName() != null,
() -> new EntityNotFoundException("Address already in use for another address"));
}
Consider using java.util.Optional since the behavior that you are trying to achieve is already there. I find it far more elegant than if (smth != null) checks.
Optional.ofNullable(employee)
.map(Employee::getAddressName)
.orElseThrow(() -> new EntityNotFoundException("Employee already in use for another address");
In general, I prefer Optional mainly because one would probably nest multiple ifs or chain the conditions if null check for entity was also needed (not the case for this question). Then you would need something like if (entity != null && entity.getAddress() == null) {throw ...} which is ugly and far less readable than the chained version with Optional. The latter statement, of course, is also a bit of syntactic taste.
Related
If a 3rd party requests an argument attachments in a method, how may I avoid using an if and break method chaining, knowing that my argument may be null? The method has the following definition.
// import org.jetbrains.annotations.NotNull;
EmailBuilder withAttachments(#NotNull List<Attachment> attachments);
I would prefer NOT using an if condition for .withAttachments, when attachments == null. I know that javascript has method?(), but what is appropriate for java8, or above? In the case where (attachments == null), I don't want to call .withAttachments() at all. But, I don't see syntax comparable to methodA?() like in javascript, or typescript.
return emailBuilder()
.withSubject(email.getSubject())
.withReplyTo(replyAddresses)
.withAttachments(attachments) // This is conditional...based on attachments
.withHeader("X-showheader", email.getShowHeader());
.build();
Would I be required to do this?
EmailBuilder eb = emailBuilder()
.withSubject(email.getSubject())
.withReplyTo(replyAddresses);
if(attachments)
eb = eb.withAttachments(attachments); // This is conditional...based on attachments
eb = eb.withHeader("X-showheader", email.getHeader())
.build;
return eb;
If withAttachments() doesn't allow a null value, then yes, you need if (attachments != null).
But, since builders don't (generally) require a specific order of method calls, you can clean the code up a bit.
EmailBuilder eb = emailBuilder()
.withSubject(email.getSubject())
.withReplyTo(replyAddresses)
.withHeader("X-showheader", email.getHeader());
if (attachments != null)
eb.withAttachments(attachments);
return eb.build();
I'm assuming you can't change the contract of withAttachments to ignore calls with null? You could, upstream wrap attachments in an Optional and then provide an orElse with an empty, but not null, impl of whatever type attachments is, e.g. (assuming attachments is a List):
Optional<...> optionalAttachments = Optional.ofNullable(attachments);
...
.withAttachments(optionalAttachments.orElse(Collections.emptyList())
UPDATE (based on input from comment, hat tip to Andreas)
You could also achieve this with a ternary, e.g.:
.withAttachments(attachments != null ? attachments : Collections.emptyList())
Here is the approach you can use if you can edit or extend the builder.
public class ChainBuilder {
public ChainBuilder ifApplicable(
Supplier<Boolean> filter,
Consumer<ChainBuilder> extension) {
if (filter.get()) {
extension.accept(this);
}
return this;
}
public ChainBuilder withAttribute1(String attribute1) {
//handle store attribute1;
return this;
}
public ChainBuilder withAttribute2(String attribute2) {
//handle store attribute2;
return this;
}
public SomeData build() {
return new SomeDate(); //with the optional attributes
}
}
The client code can chain the methods:
SomeData data = new ChainBuilder()
.withAttribute1("A")
.ifApplicable(() -> false, builder -> builder.withAttribute2("B"))
.build();
It is just an illustration. If you have several conditions, it might make sense to inlcude this into the builder class.
I have one class, let's call it ClassA, and a bunch of subclasses of it, and subsequent subclasses of those classes. ClassA, and every class below it takes a String at an argument in their constructor. I have a bunch of String objects that I need to 'convert' into subclasses of ClassA.
The current way I am doing it is with is isType(String) method that checks if the String is an instance of that subclass, but it seems like very bad programming technique to use a huge if-else or switch-case statement to find the correct type of ClassA that the String is. It there a common way to go down a sub-class structure, or is the way that I have been doing it okay?
The purpose of this is that I am making a scripting language (for a fun project) and I need to be able identify what something is. (Data type that is)
Example code:
public static boolean isType(String data) {
data = data.trim();
return edu.ata.script.data.Boolean.isType(data)
|| edu.ata.script.data.Integer.isType(data)
|| edu.ata.script.data.Double.isType(data)
|| DATA_STORAGE.contains(data)
|| ReturningMethod.isType(data)
|| edu.ata.script.data.String.isType(data);
}
public static Data get(String data) {
data = data.trim();
/*:)*/ if (edu.ata.script.data.Boolean.isType(data)) {
return edu.ata.script.data.Boolean.get(data);
} else if (edu.ata.script.data.Integer.isType(data)) {
return edu.ata.script.data.Integer.get(data);
} else if (edu.ata.script.data.Double.isType(data)) {
return edu.ata.script.data.Double.get(data);
} else if (DATA_STORAGE.contains(data)) {
return (Data) DATA_STORAGE.get(data);
} else if (ReturningMethod.isType(data)) {
return ReturningMethods.getMethodValue(data);
} else if (edu.ata.script.data.String.isType(data)) {
// Last option because everything is accepted.
return edu.ata.script.data.String.get(data);
} else {
throw new RuntimeException("Could not parse data - " + data);
}
}
I was indeed understanding something totally different, so I'm re-editing this answer.
I suspect that you're working in some sort of importation script or something and that the edu.ata.script.data.* are the ClassB, ClassC, etc that you were writing and they know how to convert stuff from one format to another... (This is just guessing)
My suggestion to get rid of all the if then else in the get(String data) method is that you implement a chain of responsability. That way you can have a chain that registers the several edu.ata.script.data.* in a List and then you iterate through that list until one of them returns true for the isType(string) knowing which subclass you want to use to process the string.
To remove the list of ORs in the isType(String data) method is a bit trickier and probably this is a bit over enginnering, but you can do the following:
Look in your classpath for classes that are assignableFrom your class
Then when you would retrieve all the classes that were assignable by your own you would have to invoke via reflection the isType of each one to know the result
I know you might find yourself a bit lost regarding the 1st point, best way is to look into ResolverUtil class from Stripes Framework where they do that in the method loadImplementationsFromContextClassloader
It looks like you are trying to parse a string into an instance of the correct subclass, by passing it to each subclass's isType method until one says it can handle it. I would have each subclass register a parser object which can inspect the string and produce an initialised instance of the corresponding subclass if possible.
Interface for the Parsers:
package edu.ata.script.data;
interface ScriptParser {
public boolean isType(String data);
public Data get(String data) throws UnparsableException;
}
An example Data subclass:
package edu.ata.script.data;
public class Boolean extends Data {
// Empty constructor for reflection purposes
public Boolean() {};
public Boolean(String data) {
// Initialise from string
}
public ScriptParser getParser() {
return new ScriptParser() {
public boolean isType(String data) {
return "true".equals(data) || "false".equals(data);
}
public Data get(String data) throws UnparsableException {
if (isType(data)) {
return new edu.ata.script.data.Boolean(data);
} else {
throw new UnparsableException(data);
}
}
};
}
}
Then you can just build a list of classes into a collection before parsing:
List<ScriptParser> parsers = new LinkedList<>();
parsers.add(new edu.ata.script.data.Boolean().getParser());
parsers.add(new edu.ata.script.data.Integer().getParser());
parsers.add(new edu.ata.script.data.Double().getParser());
...
The above could also be achieved via reflection.
Then you can parse the data with a simple loop, no matter how many data types you end up supporting:
public Data get(String data) throws SyntaxErrorException {
for (ScriptParser sp:parsers) {
if (sp.isType(data)) {
try {
return sp.get(data);
} catch (UnparsableException e) {
// This shouldn't happen, but better safe than sorry!
e.printStackTrace();
}
}
}
throw new SyntaxErrorException(data);
}
I was wondering if this approach was correct :
public ITask getState()
{
statePredicate[Some predicate definition];
ITask nextRunnable = null;
try {
nextRunnable = Iterables.find((Iterable)queue, statePredicate);
}
catch (NoSuchElementException e)
{}
return nextRunnable;
}
The points on which I am wondering are :
should the predicate be cached as a member of the class ?
I do nothing with the catch, I do not even log it because it is
normal for my app to not find anything.
t return null because I do a final return.
Thank you for your input !
-
1) If the predicate is always the same, I would make it a static final class member.
2) There is also a version of Iterables.find that you can specify a default value to (assuming you're using Google Guava). Then you don't need to deal with the NoSuchElementException at all.
3) Is there a reason to cast queue to Iterable? If this is not necessary, then don't cast.
class MyClass {
private static final Predicate STATE_PREDICATE = new Predicate<ITask>() {
#Override
public boolean apply(ITask input) {
// ... your code here
}
};
public ITask getState() {
return Iterables.find(queue, STATE_PREDICATE, null);
}
}
If the exception is really the usual case in your approach than you should put at least a comment into the catch area to make clear for everyone who reads the code that it was intentional and not a mistake. In my opinion returning Null is something different, but it some circumstanced not avoidable.
This is the second time I found myself writing this kind of code, and decided that there must be a more readable way to accomplish this:
My code tries to figure something out, that's not exactly well defined, or there are many ways to accomplish it. I want my code to try out several ways to figure it out, until it succeeds, or it runs out of strategies. But I haven't found a way to make this neat and readable.
My particular case: I need to find a particular type of method from an interface. It can be annotated for explicitness, but it can also be the only suitable method around (per its arguments).
So, my code currently reads like so:
Method candidateMethod = getMethodByAnnotation(clazz);
if (candidateMethod == null) {
candidateMethod = getMethodByBeingOnlyMethod(clazz);
}
if (candidateMethod == null) {
candidateMethod = getMethodByBeingOnlySuitableMethod(clazz);
}
if (candidateMethod == null) {
throw new NoSuitableMethodFoundException(clazz);
}
There must be a better way…
Edit: The methods return a method if found, null otherwise. I could switch that to try/catch logic, but that hardly makes it more readable.
Edit2: Unfortunately, I can accept only one answer :(
To me it is readable and understandable. I'd simply extract the ugly part of the code to a separate method (following some basic principles from "Robert C.Martin: Clean Code") and add some javadoc (and apologies, if necessary) like that:
//...
try {
Method method = MethodFinder.findMethodIn(clazz);
catch (NoSuitableMethodException oops) {
// handle exception
}
and later on in MethodFinder.java
/**
* Will find the most suitable method in the given class or throw an exception if
* no such method exists (...)
*/
public static Method findMethodIn(Class<?> clazz) throws NoSuitableMethodException {
// all your effort to get a method is hidden here,
// protected with unit tests and no need for anyone to read it
// in order to understand the 'main' part of the algorithm.
}
I think for a small set of methods what you're doing is fine.
For a larger set, I might be inclined to build a Chain of Responsibility, which captures the base concept of trying a sequence of things until one works.
I don't think that this is such a bad way of doing it. It is a bit verbose, but it clearly conveys what you are doing, and is easy to change.
Still, if you want to make it more concise, you can wrap the methods getMethod* into a class which implements an interface ("IMethodFinder") or similar:
public interface IMethodFinder{
public Method findMethod(...);
}
Then you can create instances of you class, put them into a collection and loop over it:
...
Method candidateMethod;
findLoop:
for (IMethodFinder mf: myMethodFinders){
candidateMethod = mf.findMethod(clazz);
if (candidateMethod!=null){
break findLoop;
}
}
if (candidateMethod!=null){
// method found
} else {
// not found :-(
}
While arguably somewhat more complicated, this will be easier to handle if you e.g. need to do more work between calling the findMethods* methods (such as more verification that the method is appropriate), or if the list of ways to find methods is configurable at runtime...
Still, your approach is probably OK as well.
I'm sorry to say, but the method you use seems to be the widely accepted one. I see a lot of code like that in the code base of large libraries like Spring, Maven etc.
However, an alternative would be to introduce a helper interface that can convert from a given input to a given output. Something like this:
public interface Converter<I, O> {
boolean canConvert(I input);
O convert(I input);
}
and a helper method
public static <I, O> O getDataFromConverters(
final I input,
final Converter<I, O>... converters
){
O result = null;
for(final Converter<I, O> converter : converters){
if(converter.canConvert(input)){
result = converter.convert(input);
break;
}
}
return result;
}
So then you could write reusable converters that implement your logic. Each of the converters would have to implement the canConvert(input) method to decide whether it's conversion routines will be used.
Actually: what your request reminds me of is the Try.these(a,b,c) method in Prototype (Javascript).
Usage example for your case:
Let's say you have some beans that have validation methods. There are several strategies to find these validation methods. First we'll check whether this annotation is present on the type:
// retention, target etc. stripped
public #interface ValidationMethod {
String value();
}
Then we'll check whether there's a method called "validate". To make things easier I assume, that all methods define a single parameter of type Object. You may choose a different pattern. Anyway, here's sample code:
// converter using the annotation
public static final class ValidationMethodAnnotationConverter implements
Converter<Class<?>, Method>{
#Override
public boolean canConvert(final Class<?> input){
return input.isAnnotationPresent(ValidationMethod.class);
}
#Override
public Method convert(final Class<?> input){
final String methodName =
input.getAnnotation(ValidationMethod.class).value();
try{
return input.getDeclaredMethod(methodName, Object.class);
} catch(final Exception e){
throw new IllegalStateException(e);
}
}
}
// converter using the method name convention
public static class MethodNameConventionConverter implements
Converter<Class<?>, Method>{
private static final String METHOD_NAME = "validate";
#Override
public boolean canConvert(final Class<?> input){
return findMethod(input) != null;
}
private Method findMethod(final Class<?> input){
try{
return input.getDeclaredMethod(METHOD_NAME, Object.class);
} catch(final SecurityException e){
throw new IllegalStateException(e);
} catch(final NoSuchMethodException e){
return null;
}
}
#Override
public Method convert(final Class<?> input){
return findMethod(input);
}
}
// find the validation method on a class using the two above converters
public static Method findValidationMethod(final Class<?> beanClass){
return getDataFromConverters(beanClass,
new ValidationMethodAnnotationConverter(),
new MethodNameConventionConverter()
);
}
// example bean class with validation method found by annotation
#ValidationMethod("doValidate")
public class BeanA{
public void doValidate(final Object input){
}
}
// example bean class with validation method found by convention
public class BeanB{
public void validate(final Object input){
}
}
You may use Decorator Design Pattern to accomplish different ways of finding out how to find something.
public interface FindMethod
{
public Method get(Class clazz);
}
public class FindMethodByAnnotation implements FindMethod
{
private final FindMethod findMethod;
public FindMethodByAnnotation(FindMethod findMethod)
{
this.findMethod = findMethod;
}
private Method findByAnnotation(Class clazz)
{
return getMethodByAnnotation(clazz);
}
public Method get(Class clazz)
{
Method r = null == findMethod ? null : findMethod.get(clazz);
return r == null ? findByAnnotation(clazz) : r;
}
}
public class FindMethodByOnlyMethod implements FindMethod
{
private final FindMethod findMethod;
public FindMethodByOnlyMethod(FindMethod findMethod)
{
this.findMethod = findMethod;
}
private Method findByOnlyMethod(Class clazz)
{
return getMethodOnlyMethod(clazz);
}
public Method get(Class clazz)
{
Method r = null == findMethod ? null : findMethod.get(clazz);
return r == null ? findByOnlyMethod(clazz) : r;
}
}
Usage is quite simple
FindMethod finder = new FindMethodByOnlyMethod(new FindMethodByAnnotation(null));
finder.get(clazz);
... I could switch that to try/catch logic, but that hardly makes it more readable.
Changing the signature of the get... methods so you can use try / catch would be a really bad idea. Exceptions are expensive and should only be used for "exceptional" conditions. And as you say, the code would be less readable.
What is bothering you is the repeating pattern used for flow control--and it should bother you--but there isn't too much to be done about it in Java.
I get really annoyed at repeated code & patterns like this, so for me it would probably be worth it to extract the repeated copy & paste control code and put it in it's own method:
public Method findMethod(Class clazz)
int i=0;
Method candidateMethod = null;
while(candidateMethod == null) {
switch(i++) {
case 0:
candidateMethod = getMethodByAnnotation(clazz);
break;
case 1:
candidateMethod = getMethodByBeingOnlyMethod(clazz);
break;
case 2:
candidateMethod = getMethodByBeingOnlySuitableMethod(clazz);
break;
default:
throw new NoSuitableMethodFoundException(clazz);
}
return clazz;
}
Which has the disadvantage of being unconventional and possibly more verbose, but the advantage of not having as much repeated code (less typos) and reads easier because of there being a little less clutter in the "Meat".
Besides, once the logic has been extracted into it's own class, verbose doesn't matter at all, it's clarity for reading/editing and for me this gives that (once you understand what the while loop is doing)
I do have this nasty desire to do this:
case 0: candidateMethod = getMethodByAnnotation(clazz); break;
case 1: candidateMethod = getMethodByBeingOnlyMethod(clazz); break;
case 2: candidateMethod = getMethodByBeingOnlySuitableMethod(clazz); break;
default: throw new NoSuitableMethodFoundException(clazz);
To highlight what's actually being done (in order), but in Java this is completely unacceptable--you'd actually find it common or preferred in some other languages.
PS. This would be downright elegant (damn I hate that word) in groovy:
actualMethod = getMethodByAnnotation(clazz) ?:
getMethodByBeingOnlyMethod(clazz) ?:
getMethodByBeingOnlySuitableMethod(clazz) ?:
throw new NoSuitableMethodFoundException(clazz) ;
The elvis operator rules. Note, the last line may not actually work, but it would be a trivial patch if it doesn't.
Let's say I'd like to perform the following command:
house.getFloor(0).getWall(WEST).getDoor().getDoorknob();
To avoid a NullPointerException, I'd have to do the following if:
if (house != null && house.getFloor(0) && house.getFloor(0).getWall(WEST) != null
&& house.getFloor(0).getWall(WEST).getDoor() != null) ...
Is there a way or an already existing Utils class that does this more elegantly, let's say something like the following?
checkForNull(house.getFloor(0).getWall(WEST).getDoor().getDoorknob());
In case you can't avoid breaking Law of Demeter (LoD) as stated in the chosen answer, and with Java 8 introducing Optional, it would be probably the best practice to handle nulls in chains of gets such as yours.
The Optional type will enable you to pipe multiple map operations (which contain get calls) in a row. Null checks are automatically handled under the hood.
For example, when the objects aren't initialized, no print() will be made and no Exceptions will be thrown. It all we be handled gently under the hood. When objects are initialized, a print will be made.
System.out.println("----- Not Initialized! -----");
Optional.ofNullable(new Outer())
.map(out -> out.getNested())
.map(nest -> nest.getInner())
.map(in -> in.getFoo())
.ifPresent(foo -> System.out.println("foo: " + foo)); //no print
System.out.println("----- Let's Initialize! -----");
Optional.ofNullable(new OuterInit())
.map(out -> out.getNestedInit())
.map(nest -> nest.getInnerInit())
.map(in -> in.getFoo())
.ifPresent(foo -> System.out.println("foo: " + foo)); //will print!
class Outer {
Nested nested;
Nested getNested() {
return nested;
}
}
class Nested {
Inner inner;
Inner getInner() {
return inner;
}
}
class Inner {
String foo = "yeah!";
String getFoo() {
return foo;
}
}
class OuterInit {
NestedInit nested = new NestedInit();
NestedInit getNestedInit() {
return nested;
}
}
class NestedInit {
InnerInit inner = new InnerInit();
InnerInit getInnerInit() {
return inner;
}
}
class InnerInit {
String foo = "yeah!";
String getFoo() {
return foo;
}
}
So, with your getters chain it will look like this:
Optional.ofNullable(house)
.map(house -> house.getFloor(0))
.map(floorZero -> floorZero.getWall(WEST))
.map(wallWest -> wallWest.getDoor())
.map(door -> wallWest.getDoor())
The return of it will be something like Optional<Door> which will allow you much safer work without worrying of null exceptions.
In order to check a chain of gets for null you may need to call your code from a closure. The closure call code will look like this:
public static <T> T opt(Supplier<T> statement) {
try {
return statement.get();
} catch (NullPointerException exc) {
return null;
}
}
And you call it using the following syntax:
Doorknob knob = opt(() -> house.getFloor(0).getWall(WEST).getDoor().getDoorknob());
This code is also type safe and in general works as intended:
Returns an actual value of the specified type if all the objects in the chain are not null.
Returns null if any of the objects in the chain are null.
You may place opt method into shared util class and use it everywhere in your application.
The best way would be to avoid the chain. If you aren't familiar with the Law of Demeter (LoD), in my opinion you should. You've given a perfect example of a message chain that is overly intimate with classes that it has no business knowing anything about.
Law of Demeter: http://en.wikipedia.org/wiki/Law_of_Demeter
You could of course simply wrap the whole expression up in a try-catch block, but that's a bad idea. Something cleaner is the Null object pattern. With that, if your house doesn't have floor 0, it just returns a Floor that acts like a regular Floor, but has no real content; Floors, when asked for Walls they don't have, return similar "Null" Walls, etc, down the line.
Make sure things that can't logically be null are not. For example - a house always has a West wall. In order to avoid such exceptions in state, you can have methods to check whether the state you expect is present:
if (wall.hasDoor()) {
wall.getDoor().etc();
}
This is essentially a null-check, but might not always be.
The point is that you should do something in case you have a null. For example - return or throw an IllegalStateException
And what you shouldn't do - don't catch NullPointerException. Runtime exceptions are not for catching - it is not expected that you can recover from them, nor it is a good practice to rely on exceptions for the logic flow. Imagine that you actually don't expect something to be null, and you catch (and log) a NullPointerException. This will not be very useful information, since many things can be null at that point.
Better solution for me is to use java.util.Optional.map(..) to chain these checks : https://stackoverflow.com/a/67216752/1796826
There is no checkForNull method that you can write that will facilitate this (that's simply not how method invokation and argument evaluation works in Java).
You can break down the chained statements into multiple statements, checking at every step. However, perhaps a better solution is to not have these methods return null in the first place. There is something called the Null Object Pattern that you may want to use instead.
Related questions
How to avoid != null statements in Java?
You could potentially have a generic method like below:
public static <T> void ifPresentThen(final Supplier<T> supplier, final Consumer<T> consumer) {
T value;
try {
value = supplier.get();
} catch (NullPointerException e) {
// Don't consume "then"
return;
}
consumer.accept(value);
}
So now you would be able to do
ifPresentThen(
() -> house.getFloor(0).getWall(WEST).getDoor().getDoorknob(),
doorKnob -> doSomething());
implementing nullPointer try/catch with a Supplier you can send it all chain of get
public static <T> T getValue(Supplier<T> getFunction, T defaultValue) {
try {
return getFunction.get();
} catch (NullPointerException ex) {
return defaultValue;
}
}
and then call it in this way.
ObjectHelper.getValue(() -> object1.getObject2().getObject3().getObject4()));
Very old question, but still adding my suggestion:
I would suggest instead of getting the DoorKnob from deep within the House in one method call chain, you should try to let the DoorKnob be provided to this class from the calling code, or by creating a central lookup facility specifically for this purpose (e.g. a DoorKnob service)
Simplified example of design with loose coupling:
class Architect {
FloorContractor floorContractor;
void build(House house) {
for(Floor floor: house.getFloors()) {
floorContractor.build(floor);
}
}
}
class FloorContractor {
DoorMaker doorMaker;
void build(Floor floor) {
for(Wall wall: floor.getWalls()) {
if (wall.hasDoor()) {
doorMaker.build(wall.getDoor());
}
}
}
}
class DoorMaker {
Tool tool;
void build(Door door) {
tool.build(door.getFrame());
tool.build(door.getHinges());
tool.build(door.getDoorKnob());
}
}
// Example
LazyObject.from(curr).apply(A.class, A::getB).apply(B.class, B::getC).apply(C.class, C::getD).to(String.class);
// LazyObject.java
public class LazyObject {
private Object value;
private LazyObject(Object object) {
this.value = object;
}
public <F, T> LazyObject apply(Class<F> type, Function<F, T> func) {
Object v = value;
if (type.isInstance(v)) {
value = func.apply(type.cast(v));
} else {
value = null; // dead here
}
return this;
}
public <T> void accept(Class<T> type, Consumer<T> consumer) {
Object v = value;
if (type.isInstance(v)) {
consumer.accept(type.cast(v));
}
}
public <T> T to(Class<T> type) {
Object v = value;
if (type.isInstance(v)) {
return type.cast(v);
}
return null;
}
public static LazyObject from(Object object) {
return new LazyObject(object);
}
}