Java 反射:此成员变量是否对应于此字段

Java 反射:此成员变量是否对应于此字段,java,reflection,Java,Reflection,假设我有一个带有成员变量intc的类。 假设我还有一个字段f。我想检查f是否表示c。我可以做到: f.getName().equals("c") 但是我正在寻找一种解决方案,如果我要重命名c,编译器会以某种方式提醒我。类似于f==c.getField() 我的猜测是没有办法做到这一点,但我想确认一下 使用assert语句和-ea开关,可以验证字段名称是否保持不变 根据以下公式,我们可以推断这是使用它们的适用情况: 每个断言都包含一个布尔表达式,您认为该表达式在断言执行时为真。如果不正确,系统将

假设我有一个带有成员变量
intc
的类。 假设我还有一个
字段f
。我想检查
f
是否表示
c
。我可以做到:

f.getName().equals("c")
但是我正在寻找一种解决方案,如果我要重命名
c
,编译器会以某种方式提醒我。类似于
f==c.getField()


我的猜测是没有办法做到这一点,但我想确认一下

使用
assert
语句和
-ea
开关,可以验证字段名称是否保持不变

根据以下公式,我们可以推断这是使用它们的适用情况:

每个断言都包含一个布尔表达式,您认为该表达式在断言执行时为真。如果不正确,系统将抛出错误。通过验证布尔表达式确实为真,断言确认了您对程序行为的假设,增加了您对程序没有错误的信心

异常用于捕获异常行为,断言用于验证不变假设

话虽如此:从问题描述中不清楚您的设置到底是什么样子的,但这段代码将按照我的解释执行:

public class Main {
    int c = 5;

    public static void main(String[] args) {
        Field f = null;
        try {
            f = ReflectionTest.class.getDeclaredField("c");
        } catch (NoSuchFieldException | SecurityException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }

        assert hasMember(f);

        System.out.println("We reached this point");
    }

    private static boolean hasMember(Field f) {
        for (Field localField : Main.class.getDeclaredFields()) {
            if (localField.getName().equals(f.getName())) {
                return true;
            }
        }

        return false;
    }
}

class ReflectionTest {
    int c = 10;
}
使用
intc=5
将在
IntA=5时简单打印“我们到达了这一点”将显示一个不错的错误:

Exception in thread "main" java.lang.AssertionError
at Main.main(Main.java:38)

没有像类文本那样的字段文本。这基本上意味着引用字段的唯一方法是通过其名称的
字符串
值。您将无法获得字段的IDE重构功能,我想这就是您想要此功能的原因

public class Example {} ==> public class Refactored
... 
Example.class ==> Refactored.class // would cause compiler error if wasn't changed

您需要在运行时以这种或那种方式执行此检查。

据我所知,没有办法执行此检查+你不能这样做
Field
是类成员的运行时表示形式,无法在编译时检查我们谈论的是哪个类成员。我认为没有任何方法可以在重命名时不重新编码,但您可以通过将字段标识符的一些记录放在其声明旁边来将错误风险降至最低。例如,您可以有一个包含标识符的字符串变量。您可以在单元测试中断言它吗?这或多或少是“编译时”,您不能对照字段名称进行检查,但可以对照其注释进行检查,如果您可以选择使用注释的话。