0

In Java, Is there a way to scan an object for any/all null values, and set them to a default value, no matter their Object class? (Longs, Booleans, Strings, etc).

Syntactically I'd imagine it would be similar to this, or simpler

for(key in obj){
    if(key == null && key.isString()) key.setValue("Undefined"); 
    if(key == null && key.isLong()) key.setValue(000); 
    //so on and so fourth
}

In this case I don't want to simply catch an Exception, as I need the value set to "Undefined" when displayed on a web interface.

Thanks in advance!

Clay Banks
  • 4,483
  • 15
  • 71
  • 143

4 Answers4

1

Sort of. Note that Java differentiates between primitives and objects (that is, int and Integer are not the same. If you have, say, int i = 0, then doing i = null will raise an exception. If you have Integer i = 0, then i = null is fine).

It's possible that Java provides what you want in a simple fashion - you can do, e.g.

public class Sample {
    int i = =1;
    String = "value";
    LocalDateTime time = LocalDateTime.now();
}

etc. Depending on where the data is coming from (e.g. is it coming from a database where these fields may be null?), this may be sufficient.

EDIT: Java has defaults for class-level fields. The default for primitive types is 0 (private int i = 0; is the same as private int i;), and for objects it is null (private String s = null; is the same as private String s;).

Otherwise, if you're using a framework (e.g. Spring, JEE, etc), then they may provide a nicer way to set default values on the response you're sending back.

Is there a reason you need to set it to Undefined specifically? JavaScript will treat null values as falsey by default (e.g. var a = null; if (a) {...} else {...} will take the else path), so I'd assume that whatever is displaying the information to the end user would be able to say something along the lines of if (!field) { display("Undefined", fieldName); }.

If there is absolutely no other way to do this, then it can be done, but given the point, above, about primitives and objects being different, if you want to scan a class after construction and change all fields on a class, you're going to have a rather less fun time.

The following code will fetch every field declared in the class (but not in the super class(es)!) and set them to either -1, "value", or null, depending on the type:

    try {
        final Object o = new Object();
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field f : declaredFields) {
            f.setAccessible(true);
            if(f.getType().equals(int.class) || f.getType().equals(Integer.class)) {
                f.setInt(o, -1);
            }
            if(f.getType().equals(long.class) || f.getType().equals(Long.class)) {
                f.setLong(o, -1L);
            }
            if(f.getType().equals(double.class) || f.getType().equals(Double.class)) {
                f.setDouble(o, -1.0D);
            }
            if(f.getType().equals(float.class) || f.getType().equals(Float.class)) {
                f.setFloat(o, -1.0F);
            }
            if(f.getType().equals(byte.class) || f.getType().equals(Byte.class)) {
                f.setByte(o, (byte)-1);
            }
            if(f.getType().equals(char.class) || f.getType().equals(Character.class)) {
                f.setChar(o, (char)-1);
            }
            if(f.getType().equals(String.class)) {
                f.set(o, "value");
            }
            else {
                f.set(o, null);
            }
        }
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

I'd strongly advise looking for a simpler way to do what you want, if at all possible.

ipsi
  • 2,049
  • 18
  • 23
1

You can make user of reflection like the following :

  import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Scanner;

 public class Main {
public static void main(String[] args) throws IllegalArgumentException,  IllegalAccessException, InstantiationException {
 User user=new User("Islam",null);

Field[] fields = user.getClass().getDeclaredFields();
for(Field f : fields){
 f.setAccessible(true);
 if(f.get(user)==null){
     Object val=null;
     if(Number.class.isAssignableFrom(f.getType())){
         val=0;
     }else if(Boolean.class.isAssignableFrom(f.getType())){
         val=false;
     }//complete with other types
     f.set(user, val);

 }
}
System.out.println("user name : "+user.getName());
System.out.println("user age : "+user.getAge());

}

}

class User{
private String name;
private Integer age;
User(){

}
User(String name,Integer age){
    this.name=name;
    this.age=age;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public Integer getAge() {
    return age;
}
public void setAge(Integer age) {
    this.age = age;
}


}
emad omara
  • 498
  • 2
  • 5
  • 16
0

Wondering why would you set it to default value and not throw exception. Since the usecase is not clearly understood here, did you try using ConcurrentHashMap? It will not allow your key to be null.

The Roy
  • 2,178
  • 1
  • 17
  • 33
0

I think you want to do something like this example, if so then Java reflection can help you in achieving your goal.

import java.lang.reflect.Field;

public class Testing {
Integer x;//Will be null by default
Integer y;//Will be null by default
Integer z=1;
public static void main(String[] args) {
    try {
        Testing testing = new Testing();
        Field[] fs = testing.getClass().getDeclaredFields();
        for (Field field : fs) {
            field.setAccessible(true);
            if (field.get(testing) == null && field.getName().equals("y")) {
                field.set(testing, 2);
            }
        }
        System.out.println(testing.x);//Prints null
        System.out.println(testing.y);//Prints 2
    }catch(Exception e){
        e.printStackTrace();
    }

  }
}
saurav
  • 972
  • 11
  • 24
  • This will cause problems if the field is anything apart from `Integer`, `int`, `float`, `double`, or `long`. – ipsi Feb 06 '16 at 20:47
  • @ipsi I don't think so, give us a reference and explain the possible problem. Just tested with field type String too. – saurav Feb 06 '16 at 20:54
  • That comment was based on your original answer, where you were not checking the field name. Even so, if you have `Long y;` and then do `field.set(testing, 2)` (assuming `field` is for `y`), then it will raise an exception. – ipsi Feb 06 '16 at 20:56