I have to check null condition for too many methods. how can i do it in generic way rather than repeating the same steps or Is it possible to write?
Here's my code:
<Student>
<Name></Name>
<RollNumber></RollNumber>
</Student>
I should throw an exception If user gives null value for Name or RollNumber field. I have already written code below. which is working correctly but i need to write generic method for both scenario and it should work the same as below,
if(student.getName() == null) {
System.out.println("Name is required to create Student Data");
}
if(student.getRollNumber() == null) {
System.out.println("RollNumber is required to create Student Data");
}
Note : Name is String and RollNumber is an Integer
Can you please give me an IDEA?
This question may already have an answer here:
Avoiding “!= null” statements in Java? 44 answers
My Question is "I don't want avoiding null statement. If user gives null value How Can we throw an exception in generic way?"
If your Student bean always requires non-null values how about constructing the student object with non-null values inside a constructor. As you are doing the validation inside the constructor only no need to the do the same whenever you are using that object
public class Student
{
private String name;
private String rollNumber;
public Student(String name, String rollNumber)
{
setName(name);
setRollNumber(rollNumber);
}
public String getName()
{
return name;
}
public String getRollNumber()
{
return rollNumber;
}
public String setName(String name)
{
if(isNull(name))
{
throw new NullPointerException("Name is required to create Student Data");
}
this.name= name;
}
public String setRollNumber(String rollNumber)
{
if(isNull(rollNumber))
{
throw new NullPointerException("Roll Number is required to create Student Data");
}
this.rollNumber = rollNumber
}
private void isNull(String str)
{
if(str == null || str.trim().isEmpty())
return true;
return false;
}
}
You should probably take a look at Hibernate Validation. Then you can simply annotate the fields of your bean with #NotNull.
As a bonus you can handle other validations as well.
You can use the Apache Commons String Utils API , which defines operations on String that are null safe.
You can do something like this:-
if (StringUtils.isEmpty(student.getName()) { //this check for both empty String and null and prevents null pointer exceptions
System.out.println("Name is required to create Student Data");
}
Besides null comparison for just Strings, Assertions are good way to handle nulls you can check here for more info. Make sure to pass -ea argument to JVM as by default it ignores Assertions
Related
First of all, sorry if my question seems basic. I suppose I have one class with 100 properties and 100 getters and setters.
I'm aiming check not null value of some of these properties.
Exemple :
If (object.getPropertyName()==null) System.out.println(" null value of Property Name")
I wana do this for 50 properties. I could provide a list of properties to be checked in input. Is there anyway to capture getter name by property name and check them one by one without writing this 50 times ?
Thanks
Yes sure, you can use this library here: de.cronn.reflection-util.
It allows you to obtain descriptors from specific field names and then call their respective get/set methods. Like in the following source code:
public class Test {
public static void main(String[] args) {
Example example = new Example();
example.setName("Test");
PropertyDescriptor descriptor = PropertyUtils.getPropertyDescriptorByName(example, "name");
System.out.println((String) PropertyUtils.read(example, descriptor)); // Will call getName
}
}
public class Example {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is a general issue/problem that I have come across. I wondered if anyone knows of any well suited design patterns or techniques.
private ExternalObject personObject;
private String name;
private int age;
private String address;
private String postCode;
public MyBuilderClass(ExternalObject obj)
this.personObject=obj;
build();
}
public build() {
setName(personObject.getName());
setAge(personObject.getAge());
setAddress(personObject.getAddress());
setPostCode(personObject.getPostCode());
.
.
. many more setters
}
The class above takes external objects from a queue and constructs MyBuilderClass objects.
A MyBuilderClass object is successfully built if all of the fields have been set to non-null non-empty values.
There will be many MyBuilderClass objects that cannot be built because data will be missing from the ExternalObject.
My problem, what is the best way to detect if an object has been correctly built?
I could check for null or empty values in the set methods and throw an exception. The problem with this approach is throwing exceptions is expensive and it will clogg the log files up because there will be many instances where an object cannot be built;
What other approaches could I use?
Correct me if I'm wrong: you are trying to find a good way to check if an object is valid, and if it is not, tell the client code about this without using an exception.
You can try a factory method:
private MyBuilderClass(ExternalObject obj)
this.personObject=obj;
build();
}
public static MyBuilderClass initWithExternalObject(ExternalObject obj) {
// check obj's properties...
if (obj.getSomeProperty() == null && ...) {
// invalid external object, so return null
return null;
} else {
// valid
MyBuilderClass builder = new MyBuilderClass(obj);
return builder.build();
}
}
Now you know whether an object is valid without using an exception. You just need to check whether the value returned by initWithExternalObject is null.
I wouldn't throw exceptions in cases that aren't exceptional. And as the only way for a constructor not to produce an object is to throw, you should not delay validation to the constructor.
I'd still recommend the constructor to throw if its results were to be invalid, but there should be a validation before that, so you don't even call the constructor with an invalid ExternalObject.
It's up to you if you want to implement that as a static method boolean MyBuilderClass.validate(ExternalObject) or by using the builder pattern with this validation.
Another approach for such a validation is to use java Annotations:
Make a simple annotaion class, let's say Validate:
#Target({ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
#interface Validate {
boolean required() default true;
}
then annotate the fields you want to be present as #Validate(required=true):
class MyBuilderClass {
private ExternalObject externalObject;
#Validate(required=true)
private String name;
#Validate(required=false) /*since it's a primitive field*/
private int age;
#Validate(required=true)
private String address;
#Validate(required=true)
private String postCode;
MyBuilderClass(ExternalObject externalObject) {
this.externalObject = externalObject;
build();
}
public void build() {
setName(personObject.getName());
setAge(personObject.getAge());
setAddress(personObject.getAddress());
setPostCode(personObject.getPostCode());
}
//.
//.
//. many more setters
}
And then add this method in the MyBuilderClass class, in order to check if your Object is built correctly:
public boolean isCorrectlyBuilt() throws IllegalAccessException {
boolean retVal = true;
for (Field f : getClass().getDeclaredFields()) {
f.setAccessible(true);
boolean isToBeChecked = f.isAnnotationPresent(Validate.class);
if (isToBeChecked) {
Validate validate = f.getAnnotation(Validate.class);
if (validate.required()/*==true*/) {
if (f.get(this) == null) {
retVal = false;
break;
/* return false; */
}
}
}
}
return retVal;
}
Here is an example of use :
public static void main(String[] args) throws Exception {
ExternalObject personObject = new ExternalObject();
personObject.setAge(20);
personObject.setName("Musta");
personObject.setAddress("Home");
personObject.setPostCode("123445678");
MyBuilderClass myBuilderClass = new MyBuilderClass(personObject);
System.out.println(myBuilderClass.isCorrectlyBuilt());
}
Output : true because the object is correctly built.
This will allow you to choose the fields that you want to be in the structure by reflection, without bringing those inherited from a base class.
As this previous answer suggests, here are 2 options either of which should be added after you have tried to set the variables.
use reflection to check whether any of the variables are null. (As mentioned in comments this will check all fields in this object but be careful with fields in any superclasses).
public boolean checkNull() throws IllegalAccessException {
for (Field f : getClass().getDeclaredFields())
if (f.get(this) != null)
return false;
return true;
}
perform a null check on each variable.
boolean isValidObject = !Stream.of(name, age, ...).anyMatch(Objects::isNull);
Previous answer
From what I've come across you could overwrite the equals method of your object and compare it with a valid example object. Its dirty and might only work in some cases.
Your approach is the best I could think of. Write a seperate method or class that has for example a static validate method. You could reuse it anywhere.
SOLUTION
I was adding a new instance of A to the list: aList.add( new A() ), whose name property is of course null, instead of adding the actual initialized instance. Sorry for the dumb question.
I have this A class of ProjectA which overrides its toString method to return a clone of its name property, like this:
public class A {
private String name;
#Override
public String toString() {
return new String(name);
}
}
I then export this library to a jar and import it into ProjectB and when I call a.toString() I get a NullPointerException that says there is an error exactly on the return line: return new String(name);.
However, if I put it like this:
public class A {
private String name;
#Override
public String toString() {
return name;
}
}
I don't get any exception but the String returned is null.
I built the jar (ProjectA) using Eclipse and imported it into ADT (ProjectB - Eclipse too).
NOTE:
I omitted the getters/setters intentionally for the sake of simplicity, but they're in there in the original code and I'm pretty sure I set the name property way before calling the toString() method. In fact, if I call the getName() method, the name is returned perfectly fine, but I'm using lists and I need the toString() method.
This is the part of the code where the List of A objects is created (ProjectA too):
ArrayList<A> aList = new ArrayList<Categoria>();
for (int i = 0; i < random.nextInt(3)+1; i++) {
A a = new A();
a.setId(0);
a.setName("Test name");
a.setDescription("Test desc.");
aList.add(a);
Log.d("app", "Created object A: "+a.getName()); // The name is displayed OK here
}
aList.trimToSize();
And this is the exact part of the code where the toString() method is called (ProjectA):
new ArrayAdapter<A>(
actionBar.getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
DataAccess.getAList() // The ArrayAdapter class calls the toString method to populate a list
)
As you could see, I in fact verify the content of the name property via the getName() method and it is okay. I have to mention that the first approach (the on which uses new String(name), without an finals nor null checks) worked flawlessly on another project.
This is the (relevant part of the) DataAccess class:
public final class DataAccess {
private static final Data data;
public static Arrayist<A> getAList() {
return this.data.getAList();
}
}
When you invoke new String(name); it invokes the overloaded parameterized constructor of String shown below :
public String(String original) {
int size = original.count;
........
.........
}
As you can see the first line in the code tries to compute the length of the String passed to the constructor. Since in your case the String is null invoking the member variable count on that null reference throws NullPointerException.
Note : In the code where you create AList, i dont see you adding the object to the list i.e. AList.add(a); is missing
return new String(name);
Would fail on name being null. It could happen on A a = new A(); System.out.println(a):.
The used constructor String(String) is a relict of the beginning of Java, reminiscent of the C++ copy constructor.
In Java String is immutable, and Java does not need the copy constructor.
Two solutions:
return String.valueOf(name); // Would return "null" for null.
return name == null ? "" : name;
As far as the exception goes you are getting a null pointer as already explained by #Kakarot.
This line blows up
original.count
But if you want to save yourself from null checking etc and at the same time have a efficient toString() method than user some thing like this.
public class A {
private String name = null;
private String address = " Some place";
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
return sb.append(name).append(address).toString();
}
}
Using string builder is efficient and you can see the output for the above toString() even with null values.
null Some place
In java new String(null) results into NullPointerException.
#Override
public String toString() {
if(name!=null){
return name;
}else{
return "";
}
}
I've been working on a project which has been developed by other developers. In this project, any method that returns an entity or object is designed to return a special value called EMPTY_VALUE.
public Customer getCustomer() {
if (everythingFine) {
return realCustomer();
} else {
Customer.EMPTY_VALUE;
}
}
And the Customer class:
public class Customer {
public static final Customer EMPTY_VALUE = new Customer();
private String firstName;
private STring lastName;
public Customer() {
this.firstName = "";
this.lastName = "";
}
}
In other places that use the getCustomer() method:
Customer customer = getCustomer();
if (customer != Customer.EMPTY_VALUE) {
doSomething(customer);
}
Does the above way has any advantages over the null-checking? Does it buy us anything?
Customer customer = getCustomer();
if (customer != null) {
doSomething(customer);
}
This is an example of the Null Object Pattern. The advantage is that you can remove explicit null checks by instead just using an object that does a default behavior. In this case, the null object returns empty strings when its fields are queried, so if that's what you want in the case of no result anyway, you just saved yourself a check for null. Obviously like all design patterns, its usefulness depends on the particular situation.
I don't like the idea of creating a dummy empty Customer object. What are the semantics of it? Is it a real Customer or not?
I would prefer to use something like Optional from Guava in this situation or might just use null depending on the client code. Read the description in the link to see common uses and the API for Optional.
I would say neither. Don't return null or a return special "error-object" from a method. Let them throw an exception instead. That way you don't need to "check" every time you you call it.
public Customer getCustomer() {
if (everythingFine) {
return realCustomer();
throw new NoCustomerException();
}
And the code using the method would be a lot simpler:
doSomething(getCustomer());
It could be (like the example above) an runtime exception or a checked exception.
If you have to choose between the two I would choose the non-null variant, just like I would choose to return an empty list from a method instead of null. I would however urge you not to write any special code to handle that special object, it should be handled like any other customer.
I need to make sure that no object attribute is null and add default value in case if it is null. Is there any easy way to do this, or do I have to do it manually by checking every attribute by its getters and setters?
You can use reflection to iterate over the object's field, and set them. You'd obviously need some sort of mapping between types or even field names and required default values but this can be done quite easily in a loop. For example:
for (Field f : obj.getClass().getFields()) {
f.setAccessible(true);
if (f.get(obj) == null) {
f.set(obj, getDefaultValueForType(f.getType()));
}
}
[Update]
With modern Java, you can use annotations to set the default values for fields on a per class basis. A complete implementation might look like this:
// DefaultString.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface DefaultString {
String value();
}
// DefaultInteger.java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface DefaultInteger {
int value();
}
// DefaultPojo.java:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class DefaultPojo {
public void setDefaults() {
for (Field f : getClass().getFields()) {
f.setAccessible(true);
try {
if (f.get(this) == null) {
f.set(this, getDefaultValueFromAnnotation(f.getAnnotations()));
}
} catch (IllegalAccessException e) { // shouldn't happen because I used setAccessible
}
}
}
private Object getDefaultValueFromAnnotation(Annotation[] annotations) {
for (Annotation a : annotations) {
if (a instanceof DefaultString)
return ((DefaultString)a).value();
if (a instanceof DefaultInteger)
return ((DefaultInteger)a).value();
}
return null;
}
}
// Test Pojo
public class TestPojo extends DefaultPojo {
#DefaultString("Hello world!")
public String stringValue;
#DefaultInteger(42);
public int integerValue;
}
Then default values for a TestPojo can be set just by running test.setDetaults()
You need to manually filter input to constructors and setters. Well... you could use reflection but I wouldn't advise it. Part of the job of constructors and setters is to validate input. That can include things like:
public void setPrice(double price) {
if (price < 0.0d) {
throw new IllegalArgumentException("price cannot be negative " + price);
}
this.price = price;
}
and
public void setName(String name) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
}
You could use wrapper functions for the actual check and throwing the exception.
Non-reflective solution for Java 8, without using a series of if's, would be to stream all fields and check for nullness:
return Stream.of(id, name).allMatch(Objects::isNull);
This remains quite easy to maintain while avoiding the reflection hammer.
This will return true for null attributes.
Maybe check Hibernate Validator 4.0, the Reference Implementation of the JSR 303: Bean Validation.
This is an example of an annotated class:
public class Address {
#NotNull
private String line1;
private String line2;
private String zip;
private String state;
#Length(max = 20)
#NotNull
private String country;
#Range(min = -2, max = 50, message = "Floor out of range")
public int floor;
...
}
For an introduction, see Getting started with JSR 303 (Bean Validation) – part 1 and part 2 or the "Getting started" section of the reference guide which is part of the Hibernate Validator distribution.
You can create a function that returns a boolean value and checks every attribute. You can call that function to do the job for you.
Alternatively, you can initialize the object with default values. That way there is no need for you to do any checking.
I don't have enough context to give you a correct answer, but I'll suggest you to make you code immutable as much as possible. Use public final fields. No more getters or setters : every field has to be defined by the constructor. Your code is shorter, more readable and prevents you from writing code with side effects.
It doesn't prevent you from passing null arguments to your constructor though... You can still check every argument as suggested by #cletus, but I'll suggest you to throw IllegalArgumentException instead of NullPointerException that doesn't give no new hint about what you've done.
Anyway, that's what I do as much as I can and it improved my code (readability, stability) to a great extend. Everyone in my team does so and we are very happy with that. We learned that when we try to write some erlang code where everything is immutable.
Hope this helps.
I tried this and it works without any issues to validate if the field is empty.
I have answered your question partially as I haven't personally tried to add default values to attributes
if(field.getText()!= null && !field.getText().isEmpty())
Hope it helps
This is not to check for null, instead this will be helpful in converting an existing object to an empty object(fresh object). I dont know whether this is relevant or not, but I had such a requirement.
#SuppressWarnings({ "unchecked" })
static void emptyObject(Object obj)
{
Class c1 = obj.getClass();
Field[] fields = c1.getDeclaredFields();
for(Field field : fields)
{
try
{
if(field.getType().getCanonicalName() == "boolean")
{
field.set(obj, false);
}
else if(field.getType().getCanonicalName() == "char")
{
field.set(obj, '\u0000');
}
else if((field.getType().isPrimitive()))
{
field.set(obj, 0);
}
else
{
field.set(obj, null);
}
}
catch(Exception ex)
{
}
}
}