Java 反思有用吗?

Java 反思有用吗?,java,reflection,Java,Reflection,对不起,标题是 我有一个类似foo()的方法,如下所示 public static <T> void foo(T fld1, T fld2) { // here i use some info from fld1 and some from fld2 in order // to do something } foo(a1.myField, a2.myField) 但我无法在编译时检查fieldName是否是类C的有效字段名 有一个方法会很有帮助 Field get

对不起,标题是

我有一个类似foo()的方法,如下所示

public static <T> void foo(T fld1, T fld2) {
    // here i use some info from fld1 and some from fld2 in order
    // to do something
}
foo(a1.myField, a2.myField)
但我无法在编译时检查fieldName是否是类C的有效字段名

有一个方法会很有帮助

Field getField(Object field)
所以

getField(a1.myField)
等于

a1.getClass().getField("myField")
现在我写这个方法:

public static <T> Field getField(T o, Object fld) {
    Field rv = null;
    try {
        Field[] fields = o.getClass().getFields();
        for (Field field : fields) {
            Object f = field.get(o);
            if (f==fld) {
                rv = field;
                break;
            }
        }
    } catch (Exception e) {
    }
    return rv;
}

感谢您的回答,Carlo

您可以在运行时在方法中使用
instanceOf
进行检查

举个例子:

if(fd1 instanceOf Fd1Obj)

您可以在运行时在方法中使用
instanceOf
进行检查

举个例子:

if(fd1 instanceOf Fd1Obj)
我想在编译时确定

反射是关于运行时的。 因此,它对编译时间没有帮助

我想在编译时确定

反射是关于运行时的。
因此,它对编译时间没有帮助。

静态泛型如何确保它是一个对象:

static <T extends Object> void foo(T fld1, T fld2) {
   // ...
}

静态泛型如何确保它是一个对象:

static <T extends Object> void foo(T fld1, T fld2) {
   // ...
}

您可以在调用foo(..)时指定类型,如:

yourClass.foo(a1.myField,a2.myField)

通过这种方式,您可以确保类型检查在编译时完成

但是,如果不提供类型参数,这不是强制性的,即在本例中,java文档说明:

推理算法试图找到 适用于所有参数

请看这里:


而且,对于编译时检查来说,没有反射也没有那么好的帮助。

您可以在调用foo(..)时指定类型,如:

yourClass.foo(a1.myField,a2.myField)

通过这种方式,您可以确保类型检查在编译时完成

但是,如果不提供类型参数,这不是强制性的,即在本例中,java文档说明:

推理算法试图找到 适用于所有参数

请看这里:


而且,对于编译时检查来说,没有反射是没有帮助的。

这在Java中是冗长的,但是Java8的lambdas应该让它不那么冗长。您需要的是一种编译时检查的方法,可以从C类型的对象获取T类型的值。在Java中指定接口的方法是:

public interface Getter<C, T> {
  T get(C c);
}

这在Java中是冗长的,但是Java8的lambdas应该让它不那么冗长。您需要的是一种编译时检查的方法,可以从C类型的对象获取T类型的值。在Java中指定接口的方法是:

public interface Getter<C, T> {
  T get(C c);
}

myField和另一个Field是否返回相同的类型?或者它们返回什么类型?myField和另一个Field是相同的类型(否则会出现编译错误),但我希望避免这种情况。我希望fld1和fld2是同一类的两个不同实例的同一字段myField和另一个field是否返回相同的类型?或者它们返回什么类型?myField和另一个Field是相同的类型(否则会出现编译错误),但我希望避免这种情况。我希望fld1和fld2是同一个classi know的两个不同实例的同一个字段,但它可能对编译时没有帮助,而是检查约束我知道,但可能对编译时没有帮助,而是检查约束对不起,我不明白。fld1和fld2是字段,所以我不能在fld1的类中执行
fld1.getClass().getField(“myField”)
。在fld1的类中没有“myField”字段。我用您建议的内容更改了我的问题,以便您可以看到为什么这不是我的答案。抱歉,我不明白。fld1和fld2是字段,所以我不能在fld1的类中执行
fld1.getClass().getField(“myField”)
在fld1的类中没有“myField”字段。我用您建议的其他内容更改了我的问题,以便您可以看到为什么它不是我的答案。我认为我的问题不够清楚。。。foo()方法是静态的,与特定类无关。静态方法属于类,而不属于任何特定实例。因此,当您调用它时,可以提供类型参数。我希望我能理解你。对不起,但是。。。我想fld1和fld2是同一个类的两个不同实例的同一个字段(但我不知道,也不在乎哪个是那个类),我想我的问题还不够清楚。。。foo()方法是静态的,与特定类无关。静态方法属于类,而不属于任何特定实例。因此,当您调用它时,可以提供类型参数。我希望我能理解你。对不起,但是。。。我希望fld1和fld2是同一类的两个不同实例的同一字段(但我不知道,也不在乎哪个是该类)
static <C, T> void foo(C c1, C c2, Getter<C, T> getter) {
  T fld1 = getter.get(c1);
  T fld2 = getter.get(c2);
  // ...
}
foo(a1, a2, new Getter<A, Integer>() {
    public Integer get(A a) { return a.fieldName; }
});
foo(a1, a2, a -> a.fieldName);