简体   繁体   中英

NullPointerException while using this.getClass().getDeclaredField method

I wanted to get only one field name of a POJO, my java POJO look like:

public class A1 {

        private String field2;
    private String field1;
    public String getField2() {
        return field2;
    }
    public void setField2(String field2) {
        this.field2 = field2;
    }
    public String getField1() {
        return field1;
    }
    public void setField1(String field1) {
        this.field1 = field1;
    }
    @Override
    public String toString() {
        return "A1 [field2=" + field2 + ", field1=" + field1 + "]";
    }

        public String getFiled1Name() throws NoSuchFieldException, SecurityException{
            return this.getClass().getDeclaredField(field1).getName();
        }

    }

In the client code:

System.out.println(new A1().getFiled1Name());

I am getting NullPointerException

I tried method this.getClass().getDeclaredFields() and this works as expected. But the problem with this is: It returns all the fields( java.lang.reflect.Field ) and I need to iterate, compare and then return the correct filed name.

Rather I want to get only one field name and with no hard coded field name in the method. How I can get this?

You should supply name of the field instead of field itself as field1 is String which is null and you are passing null to the getDeclaredField ,

public String getFiled1Name() throws NoSuchFieldException, SecurityException {
    return getClass().getDeclaredField("field1").getName();
}

Class#getDeclareField throws NullPointerException - if name is null


I don't want to hard code "field1"

You can create a constant for the field name instead of using reflection but for every change in name you also need to update constant.

In other way out you can get all declared fields and access the name of the field from the array. But be careful while using this as change in the declaration may change behavior of the method.

public String getFiled1Name() throws NoSuchFieldException, SecurityException {
    return getClass().getDeclaredFields()[0].getName();
}

you need to pass field name as String.

 public String getFiled1Name() throws NoSuchFieldException, SecurityException{
    return this.getClass().getDeclaredField("field1").getName();
}

Your field field1 is null. You haven't initialized the String. So that causes the NullPointerException. You're currently just passing null to the getDeclaredField() method.

I thought of this, not sure if Thread.currentThread().getStackTrace() is relaiable enugh, however you want something totally dynamic , no hardcoded... so this is my shoot:

public class Reflections {

    private String field2;
    private String field1;

    public static void main(String[] args) {
        Reflections r = new Reflections();
        System.out.println(r.getField1Name());
    }

    private Field fields[] = null;

    public Reflections() {
        fields = getClass().getDeclaredFields();
    }

    public String getField1Name() {

        if(fields == null || fields.length==0){
            return null;
        }

        final StackTraceElement[] stes = Thread.currentThread().getStackTrace();
        if(stes == null || stes.length<2){
            return null;
        }

        final String thisMethodName = stes[1].getMethodName(); // [1] this is supposed to have the name of current method

        for (Field f : fields) {
            if (thisMethodName.toLowerCase().contains(f.getName().toLowerCase())) {
                //System.out.println(f.getName());
                return f.getName();
            }// match
        }// for fields
        return null;
    }// getFiled1Name   
}

in short, getField1Name() tries to find it's own name, and then iterates through fields list of current class, and tries to find a field that it's name is part of the method name.

this could return invalid result sometimes, as some field names might be a sub-part of longer name, and some other cases where the result will not be accurate

but however, here it is, maybe it's useful for you or anyone else.

you can refactor the code, creating new method getFieldNameUsingMethodName() ?? maybe ?!?! this will do the loop and match thing, in case you have like 10 or more getFieldXname() so you can do it if you think this sol worthy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM