3

Not sure if I can do this but, say I had the object:

public class SomeObject
{
    private String field1;
    private String field2;
    ....

    //Blah Blah getters and setters for all fields
}

I want to get a count of how many of these fields are non-null. My particular object has like 40 fields so I really don't want to have a if block to check each of the 40 fields individually. I was thinking I could do this with reflection somehow? but really don't know what I am doing with it. It would be nice to just iterate through all the fields and check their value.

I feel like this is a no brainer for someone out there.

sauce
  • 592
  • 4
  • 9
  • 25

3 Answers3

6

Yes, you could do it with reflection:

SomeObject objectReference = ...; // The object you're interested in
Class clazz = SomeObject.class;
int nullCount = 0;
for (Field field : clazz.getDeclaredFields())
{
    field.setAccessible(true);
    if (field.get(objectReference) == null)
    {
        nullCount++;
    }
}

(Subject to various exceptions, permissions etc.)

This feels like a bit of a hack though... it's a somewhat strange requirement, to be honest. Do you definitely need all 40 fields, and do you need to have them as separate fields rather than (say) an array?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yes, you can, [but you don't have to](http://www.reellifewisdom.com/let_us_redefine_progress_to_mean_that_just_because_we_can_do_a_thing_it_does_not_necessarily_mean_we_must_do_that_t). – cwallenpoole Oct 25 '11 at 18:03
  • @Eng.Fouad: Not if `objectReference` is non-null... why would it? It's just getting the value of the field within that object. If the value is null, it will return null... – Jon Skeet Oct 25 '11 at 18:03
  • How about defining the class as a decorator of a HashMap? Then you get the count and storage for free. – allingeek Oct 25 '11 at 18:04
  • 1
    The class is generated from xsd and its contains address information. So I can't really change the class architecture unfortunately. And really for this project I'm doing it doesn't need to be perfect just get the job done. Aside from changing the class is this the best way to do this? – sauce Oct 25 '11 at 18:15
  • @sauce: Could be... I suspect it'll *work*, anyway. It may not be terribly fast, mind you... – Jon Skeet Oct 25 '11 at 18:18
  • Thanks for this Jon, I've been trying to do this for a while. I'm using this to ensure that an object that is made using the builder pattern is built correctly, and throwing an exception if an essential field isn't built! Thanks again! – AncientSwordRage May 15 '13 at 10:08
1

No problem you can use reflection.

SomeObject obj = new SomeObject();
//initialization
//...................

// now the code that prints all null fields
Field[] fields = SomeObject.class.getDeclaredFields();
for (Field field : fields) {
    field.setAccessible(true);
    if (field.getValue(obj) == null) {
        System.out.println(field.getName());
    }
}

Obviously you should put code like this to reusable method: you can decide where the method will be: in the class itself, in abstract base class or in utility. This depends on your project.

AlexR
  • 114,158
  • 16
  • 130
  • 208
0

This isn't a direct answer to your question and you could break it via reflective access to data members, but one option would be to have a counter data member. Something like this

public class SomeObject{
    private int numNull = {number of fields};
    private String someString;
    ...

    public void setSomeString(String string){
        --numNull;
        someString = string;
    }
 }

Then you could read the numNull property to get the number of fields without going through the overhead of using reflection (Reflection is really, really expensive). Like I said though, bad code could easily modify these parameters and bypass the setter function which would make your internal count invalid so I wouldn't rely on it.

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109