So I have a constructor with 5 different variables, where three of which might be null. It accepts user input and the user does not have to enter anything for three of the five attributes.
Therefore, if the user did not enter anything, the object is created using null for all missing values.
obj = new Object(String, null, null, null, String);
Now I am wondering what would be best practice to cope with this.
I can think of three different scenarios:
Deal with it only in the class using the constructor, i.e. always query whether the value is null (e.g. if(getSomeAttribute == null) { //do something }
Deal with it within the object class, i.e. always return some default value for each missing attribute instead of null
Deal with it within the object lcass, i.e. have helper-methods like isAttributeSet(), returning a boolean value indicating whether the attributes are set, that is: not null.
Although I have problems with the last two, as I think I might run into problems with default values, as sometimes it might hard to know if it is a default value; if I'd always check I could just as well check for null instead of inserting a default value first;
Same with the last one, if I have to check the helper-method, I could just as well check for null directly.
What my problem is with this situation, is that sometimes I might not be the one using the getter and setter methods; how should the one using it know there might be null attributes and which that are.
I know, I should document that within my object class, but still I am wondering if there is a "best practice" way to cope with this.
I believe it should be unusual to always check the documentary (or if there is none, the whole class) for something as simple as this.
Maybe I should not even start with null values within my constructor in the first place? But I think I would run into the same kinds of problems, anyway, so that would not really solve my problem
Read Bloch, Effective Java, 2nd ed. Item 2: "Consider a builder when faced with many constructor parameters."
Excellent advice in an excellent book.
Using a builder pattern would help with the constructor, however the main problem is to do with the design of the class - you want to be sure when you call a get/set method that it isn't one of the null/optional members.
You could use polymorphism to have two objects each with an interface that only exposes the getters and setters supported by the concrete implementation. This makes it impossible to call the wrong getters/setters and it is obvious what the intention is.
Related
I've been reading articles on beeing null safe in java, and how it's bad to return null, or of that sin, that is passing null as an argument. I get that it simplifies life, and people don't always read documentation, so they don't know wheather a method can return null, or if null can be passed to it. Annotations seem to just pollute the code, and there is no Kotlin-like null safety mechanism. In my current project I try to design everything in such a manner, that null is almost unnecessary, at least for the end-user.
I want to create a change listener (something like javafx.beans.value.ChangeListener), such that i can pass a previous and a current value to the changed() method. The thing is, I want it to be null safe, so I don't want to ever pass a null as an argument, even though it can change from no value to some value, or from some value to no value. I could add two additional methods for that situation and have something like:
public inteface ChangeListener<T> {
void valueSet(T current);
void valueChanged(T previous, T current);
void valueCleared(T previous);
}
This approach seems excessive though. I could also use
java.util.Optional<T> as arguments, but that adds additional boxing:
public inteface ChangeListener<T> {
void changed(Optional<T> previous, Optional<T> current);
}
Is there a more elegant option? Or should I force user to use some sort of a Null Object Pattern? Although that will create problems with the need to extend some classes. I could also stop caring, specify in the documentation what will happen if null is used, and let the user find the source of all the NullPointerExceptions.
Be a bit careful when people tell you "XYZ considered harmful". I've seen people do away with constructors altogether in favour of factory methods (such as Optional.of(...)), but as with everything, there's no single correct answer.
You seem to be struggling with trying to achieve several things (using simple code, having only one method in the listener, not using null values) that are mutually exclusive. So stop worrying and focus on what's important.
If your API users are idiots, and they don't read documentation, that's not really your problem. Null is not something dirty; it means "undefined". What is dubious is to use null if something unexpected happened, like "file not found", which should ideally be dealt with via an exception.
If "undefined" is a correct representation of an unset value in your API, then there's nothing wrong with using null.
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.
Is it a bad practice to pass NULL argument to methods or in other words should we have method definitions which allow NULL argument as valid argument.
Suppose i want two method
1. to retrieve list of all of companies
2. to retrieve list of companies based upon filter.
We can either have two methods like as below
List<Company> getAllCompaniesList();
List<Company> getCompaniesList(Company companyFilter);
or we can have one single method
List<Company> getCompaniesList(Company companyFilter);
here in second case, if argument is NULL then method return list of all of companies.
Beside question of good practice practically i see one more issue with later approach which is explained below.
I am implementing Spring AOP, in which i want to have some checks on arguments like
1. Is argument NULL ?
2. is size of collection 0?
There are some scenarios where we can not have null argument at all like for method
void addBranches(int companyId, List<Branch>);
This check can be performed very well by using Spring AOP by defining method like following
#Before(argNames="args", value="execution(* *)")
void beforeCall(JoinPoint joinPoint ,Object[] args )
{
foreach(Object obj in args)
{
if(obj == NULL)
{
throw new Exception("Argument NULL");
}
}
}
But problem i am facing is since i have defined some of methods which should accept NULL argument for multiple functionality of one single method as mentioned above for method List getCompaniesList(Company companyFilter);
So i can not apply AOP uniformly for all of methods and neither some expression for methods name match will be useful here.
Please let me know if more information is required or problem is not descriptive enough.
Thanks for reading my problem and giving thought upon it.
It's fine, in cases when there are too many overloaded methods. So instead of having all combinations of parameters, you allow some of them to be null. But if you do so, document this explicitly with
#param foo foo description. Can be null
In your case I'd have the two methods, where the first one invokes the second with a null argument. It makes the API more usable.
There is no strict line where to stop overloading and where to start relying on nullable parameters. It's a matter of preference. But note that thus your method with the most params will allow some of them to be nullable, so document this as well.
Also note that a preferred way to cope with multiple constructor parameters is via a Builder. So instead of:
public Foo(String bar, String baz, int fooo, double barr, String asd);
where each of the arguments is optional, you can have:
Foo foo = new FooBuilder().setBar(bar).setFooo(fooo).build();
I use a very simple rule:
Never allow null as an argument or return value on a public method.
I make use of Optional and Preconditions or AOP to enforce that rule.
This decision already saved me tons of hours bugfixing after NPE's or strange behaviour.
It's common practice, but there are ways of making your code clearer - avoiding null checks in sometimes, or moving them elsewhere. Look up the null object pattern - it may well be exactly what you need: http://en.m.wikipedia.org/wiki/Null_Object_pattern?wasRedirected=true
The rule is: simple interface, complicated implementation.
Design decisions about your API should be made by considering how the client code is likely to use it. If you expect to see either
getAllCompaniesList(null);
or
if (companyFilter == null) {
getAllCompaniesList();
} else {
getAllCompaniesList(companyFilter);
}
then you're doing it wrong. If the likely use-case is that the client code will, at the time it is written, either have or not have a filter, you should supply two entry points; if that decision is likely not made until run-time, allow a null argument.
Another approach that may be workable may be to have a CompanyFilter interface with an companyIsIncluded(Company) method that accepts a Company and returns true or false to say whether any company should be included. Company could implement the interface so that companyIsIncluded method's behavior mirrored equals(), but one could easily have a singleton CompanyFilter.AllCompanies whose companyIsIncluded() method would always return true. Using that approach, there's no need to pass a null value--just pass a reference to the AllComapnies singleton.
In a GWT solution. (so this is java code that is then compiled to javascript).
There are of course some classes.
Is it a good idea to make the setter check for Null on a String field?
something like this
public void setSomeField(String someField){
if (null != someField)
this.someField = someField;
else
this.someField = String.Empty;
}
Is this a good or bad idea? On the one had it will make coding easier as i wont have to check for null , on the other hand it would make me probably forget that I have to do this for other strings.
Thoughts?
Thanks
I say if such a logic is needed in your application, the setter is the place to put it. The main reason to have a get/set wrap around a private var is to be able to put logic around the access.
To answer the question of to default or not to default:
In my application it made sence to have a set of properties fall back to string.empty for display reasons. Although people could argue that the view should then cover these possibilities and check for nulls and display nothing, it was a lot of bloat all over my pages to do a check on every property.
That's why I started implementing SafeXX properties. So say I had 'myObj.Name' that could possibly have a null value, there would also be a property 'myObj.SafeName' that caught the null in the getter and returned a string.empty in stead. The little naming convention gives away that it is not the regular getter.
Here's something to consider. Would you expect this unit test to pass or fail?:
yourClass.setSomeField(null);
assertNull(yourClass.getSomeField());
If you're changing the null value to an empty string and returning that in getSomeField, then the client now has to check two conditions when testing...a String and a null String. Not a big deal, but what happens if you've got twenty String properties in the class...you'd probably better try to be consistent amongst all of the setters, and if you're not then the reason should probably be more obvious than just the documentation saying so.
There are certain conventions around getters and setters; certain expectations. If I call a setter on an object, then I usually expect the getter to return what I set. I don't expect it to return some representation of what I passed in that is more convenient for the class to work with internally. I don't care about the internals of the class, and don't want to.
If null really should be changed to "" for a valid reason (for example, it might mean "I don't care" and the default could be ""), go for it(but document it).
Otherwise, like if you just caught a NullPointerException and are trying to fix it this way, don't do it. If callers use obviously invalid values, the exception should be raised as soon as possible so that the caller notices the problem and fixes it before it bubbles up to a catastrophic, unexplainable error in a probably completely unrelated component.
In general, it is not a good idea to check for null values because the caller (the one who invokes the setter) may really want to set the value to null.
Suppose you query for 'someField' with this:
select * from ... where someField is null
If you set it as the empty string, the query above would fail.
If you don't want a field set to null, then don't set it to null.
This can be a good idea if you have no control over the code doing the setting, but if you do, it better to fix the problem at the source rather than put in work arounds like this.
That is hard to answer. On the first look it seems to make the usage better because you don't have to check for null all the time. But you loose the quality of null that means nothing is assigned. If you do String.Empty you already have ambiguity if someone gave you a String.Empty as parameter. Maybe it doesn't matter.
I personally (if at all) wouldn't do it in the setter. Inside your class null should have a value of its own. If you are for convenience a getter
return (this.someField != null) ? this.someField: String.Empty;
will do. You would keep the null internally to deal with but the outside has a more convenient method.
Generally and personally speaking I wouldn't do it. It looks good at first and makes a lot of things harder at later time.
This question is specifically related to overriding the equals() method for objects with a large number of fields. First off, let me say that this large object cannot be broken down into multiple components without violating OO principles, so telling me "no class should have more than x fields" won't help.
Moving on, the problem came to fruition when I forgot to check one of the fields for equality. Therefore, my equals method was incorrect. Then I thought to use reflection:
--code removed because it was too distracting--
The purpose of this post isn't necessarily to refactor the code (this isn't even the code I am using), but instead to get input on whether or not this is a good idea.
Pros:
If a new field is added, it is automatically included
The method is much more terse than 30 if statements
Cons:
If a new field is added, it is automatically included, sometimes this is undesirable
Performance: This has to be slower, I don't feel the need to break out a profiler
Whitelisting certain fields to ignore in the comparison is a little ugly
Any thoughts?
If you did want to whitelist for performance reasons, consider using an annotation to indicate which fields to compare. Also, this implementation won't work if your fields don't have good implementations for equals().
P.S. If you go this route for equals(), don't forget to do something similar for hashCode().
P.P.S. I trust you already considered HashCodeBuilder and EqualsBuilder.
Use Eclipse, FFS!
Delete the hashCode and equals methods you have.
Right click on the file.
Select Source->Generate hashcode and equals...
Done! No more worries about reflection.
Repeat for each field added, you just use the outline view to delete your two methods, and then let Eclipse autogenerate them.
If you do go the reflection approach, EqualsBuilder is still your friend:
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
Here's a thought if you're worried about:
1/ Forgetting to update your big series of if-statements for checking equality when you add/remove a field.
2/ The performance of doing this in the equals() method.
Try the following:
a/ Revert back to using the long sequence of if-statements in your equals() method.
b/ Have a single function which contains a list of the fields (in a String array) and which will check that list against reality (i.e., the reflected fields). It will throw an exception if they don't match.
c/ In your constructor for this object, have a synchronized run-once call to this function (similar to a singleton pattern). In other words, if this is the first object constructed by this class, call the checking function described in (b) above.
The exception will make it immediately obvious when you run your program if you haven't updated your if-statements to match the reflected fields; then you fix the if-statements and update the field list from (b) above.
Subsequent construction of objects will not do this check and your equals() method will run at it's maximum possible speed.
Try as I might, I haven't been able to find any real problems with this approach (greater minds may exist on StackOverflow) - there's an extra condition check on each object construction for the run-once behaviour but that seems fairly minor.
If you try hard enough, you could still get your if-statements out of step with your field-list and reflected fields but the exception will ensure your field list matches the reflected fields and you just make sure you update the if-statements and field list at the same time.
You can always annotate the fields you do/do not want in your equals method, that should be a straightforward and simple change to it.
Performance is obviously related to how often the object is actually compared, but a lot of frameworks use hash maps, so your equals may be being used more than you think.
Also, speaking of hash maps, you have the same issue with the hashCode method.
Finally, do you really need to compare all of the fields for equality?
You have a few bugs in your code.
You cannot assume that this and obj are the same class. Indeed, it's explicitly allowed for obj to be any other class. You could start with if ( ! obj instanceof myClass ) return false; however this is still not correct because obj could be a subclass of this with additional fields that might matter.
You have to support null values for obj with a simple if ( obj == null ) return false;
You can't treat null and empty string as equal. Instead treat null specially. Simplest way here is to start by comparing Field.get(obj) == Field.get(this). If they are both equal or both happen to point to the same object, this is fast. (Note: This is also an optimization, which you need since this is a slow routine.) If this fails, you can use the fast if ( Field.get(obj) == null || Field.get(this) == null ) return false; to handle cases where exactly one is null. Finally you can use the usual equals().
You're not using foundMismatch
I agree with Hank that [HashCodeBuilder][1] and [EqualsBuilder][2] is a better way to go. It's easy to maintain, not a lot of boilerplate code, and you avoid all these issues.
You could use Annotations to exclude fields from the check
e.g.
#IgnoreEquals
String fieldThatShouldNotBeCompared;
And then of course you check the presence of the annotation in your generic equals method.
If you have access to the names of the fields, why don't you make it a standard that fields you don't want to include always start with "local" or "nochk" or something like that.
Then you blacklist all fields that begin with this (code is not so ugly then).
I don't doubt it's a little slower. You need to decide whether you want to swap ease-of-updates against execution speed.
Take a look at org.apache.commons.EqualsBuilder:
http://commons.apache.org/proper/commons-lang/javadocs/api-3.2/org/apache/commons/lang3/builder/EqualsBuilder.html