繁体   English   中英

使用this.getClass()。getDeclaredField方法时发生NullPointerException

[英]NullPointerException while using this.getClass().getDeclaredField method

我只想获取一个POJO的字段名称,我的Java POJO如下所示:

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();
        }

    }

在客户端代码中:

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

我收到NullPointerException

我尝试了方法this.getClass().getDeclaredFields() ,这按预期工作。 但这是一个问题:它返回所有字段( java.lang.reflect.Field ),我需要进行迭代,比较然后返回正确的文件名。

而是我只想获得一个字段名,并且在该方法中没有硬编码的字段名。 我怎么能得到这个?

你应该领域,而不是场本身提供名称field1为字符串,它是null和要传递nullgetDeclaredField

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

Class#getDeclareField抛出NullPointerException如果名称为null


我不想硬编码“ field1”

您可以为字段名称创建一个常量,而不是使用反射,但是对于名称的每次更改,您还需要更新常量。

换句话说,您可以获取所有声明的字段并从数组访问字段的名称。 但是在使用它时要小心,因为声明中的更改可能会更改方法的行为。

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

您需要将字段名称传递为String。

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

您的字段field1为空。 您尚未初始化字符串。 因此,将导致NullPointerException。 当前,您只是将null传递给getDeclaredField()方法。

我想到了这个,不确定Thread.currentThread().getStackTrace()是否可靠,但是您想要完全动态的东西,没有硬编码...所以这是我的摄影:

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   
}

简而言之, getField1Name()尝试找到其自己的名称,然后遍历当前类的字段列表,并尝试查找其名称属于方法名称的字段。

有时这可能返回无效的结果,因为某些字段名称可能是较长名称的一部分,而在另一些情况下结果将不准确

但是,这可能对您或其他任何人有用。

您可以重构代码,创建新方法getFieldNameUsingMethodName() 也许 ?!?! 如果您有10个或更多的getFieldXname() ,则这将完成循环并进行匹配操作,因此,如果您认为此溶胶值得,则可以执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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