在构造期间通过反射获取Java中的静态实例名称

时间:2019-06-18 19:18:07

标签: java reflection

我不确定这是否是减少写入字符数的正确方法,但仍然如此。

现在,我有以下代码段映射到两个设置源:数据库和.properties文件:

import lombok.*;

@Getter
@ToString
@EqualsAndHashCode
public final class Setting<T> {
    private String id;
    private Class<T> clazz;  

    private Setting(final String id, final Class<T> clazz) {
        this.id = id;
        this.clazz = clazz;
    }

    public static final Setting TOKEN_LENGTH = new Setting("TOKEN_LENGTH", Integer.class);
    // lots of other settings
}

问题是,我想避免第一个参数显式传递给构造函数,例如就像名为TOKEN_LENGTH的变量已传递ID TOKEN_LENGTH一样。换句话说,当实例化这些static final变量时,它们的第一个参数始终是所述变量的名称。

在这种情况下,仅创建约60个此类的实例,并且这种情况仅在应用程序启动时发生,因此反射引起的任何开销都是可以接受的。

我想知道是否有任何方法可以重写构造函数以使其类似于

    private Setting(final Class<T> clazz) {
        this.id = /* some crazy reflection magic */
        this.clazz = clazz;
    }

所以,问题是:

➥偶然地,有什么方法可以获取实例化并为其分配对象的静态变量的名称?

UPD:

有一种解决方案,首先实例化所有变量,然后依次设置id字段。我仍在寻找在构造函数中“原子地”执行此操作的方法。

1 个答案:

答案 0 :(得分:1)

这样做相对容易,问题在于知道要使用哪个字段。您可以使用注释对其进行标记,这将使其变得更加容易。像

public String getFieldName(){
    Field[] fields = getClass().getDeclaredFields();
    for(Field f: fields){
        if(f.isAnnotationPresent(YourAnnotation.class)){
             return f.getName();
        }
    }
    // do whatever if a valid field wasn't found
}

如果您不想使用注释,则必须找到其他方法来标识它,例如唯一的静态字段。但这是非常糟糕的做法,使用注释会更好。