反射在构造函数中设置字段值

时间:2013-12-31 12:56:57

标签: java reflection

我想序列化我的配置文件,并希望使用默认值,如果文件中未定义的值,则所有值都使用值进行初始化。问题是我无法在构造函数中使用反射覆盖这些“默认值”。

public class SerializedConig {

    public SerializedConig(String value) {
        Field field;
        try {
            field = this.getClass().getDeclaredField("field");
            field.setAccessible(true);
            field.set(this, value);
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public class ExampleConfig extends SerializedConig {

    private String field;

    public ExampleConfig(String value) {
        super(value);
    }
}

2 个答案:

答案 0 :(得分:0)

我写过这个并且它正在发挥作用。我与你有什么不同?只添加了一个IllegalArgumentException和一个main方法。

import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.login.Configuration;

class SerializedConig {

    public SerializedConig(String value) {
        Field field;
        try {
            field = this.getClass().getDeclaredField("field");
            field.setAccessible(true);
            field.set(this, value);
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

public class ExampleConfig extends SerializedConig {

    private String field;

    public ExampleConfig(String value) {
        super(value);
    }

    public static void main(String[] args) {
        ExampleConfig e = new ExampleConfig("s");
        System.out.println();
    }
}

答案 1 :(得分:0)

你有一个范围问题。您将值传递给super()构造函数,但超类中的字段值不是类变量,它是局部变量。子类中的字段值是全局的,但由于这个原因,不会由super()构造函数设置。你无法覆盖它,因为它们是两个恰好具有相同名称的不同实例。

我不确定你为什么在这里使用反射,虽然我认为我可以看到你的目标,这可以通过正常的任务轻松处理。

您可以尝试以下方法:

public class SerializedConig {

    protected String field;

    public SerializedConig(String value) {
        try {
            field = this.getClass().getDeclaredField("field");
            field.setAccessible(true);
            field.set(this, value);
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public class ExampleConfig extends SerializedConig {  
    public ExampleConfig(String value) {
        super(value);
    }
}