对不起标题......
我有一个像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)
.myField
两次foo(a1.myField, a2.anotherField);
我不知道反思是否是我问题的答案。
我可以这样写:
static <C> void foo(C o1, C o2, String fieldName) {
try {
Object fld1 = o1.getClass().getField(fieldName).get(o1);
Object fld2 = o2.getClass().getField(fieldName).get(o2);
// here i use some info from fld1 and some from fld2 in order
// to do something
} catch (Exception e) {
}
}
但是如果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;
}
并以这种方式使用
getField(a1, a1.myField);
感谢任何回答,Carlo
答案 0 :(得分:2)
您可以在运行时使用方法instanceOf
进行检查。
只是示例:
if(fd1 instanceOf Fd1Obj)
答案 1 :(得分:2)
我想在编译时确定..
反思完全是关于运行时。 所以对编译时间没有帮助。
答案 2 :(得分:0)
静态通用如何确保它是一个对象:
static <T extends Object> void foo(T fld1, T fld2) {
// ...
}
您可以使用反射从对象中获取命名字段:
AType myField1 = (AType)fld1.getClass().getField("myField").get(fld1);
AType myField2 = (AType)fld2.getClass().getField("myField").get(fld2);
答案 3 :(得分:0)
您可以在调用foo(..)时指定类型,如:
yourClass.foo(a1.myField,a2.myField)。
通过这种方式,您可以确保在编译时完成类型检查。
但是,这不是强制性的,如果你不提供类型参数,即在这种情况下,java文档说:
推理算法试图找到最具体的类型 适用于所有论点。
看看这里:
http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
没有反映对编译时间检查没有帮助。
答案 4 :(得分:0)
这在Java中很冗长,但Java8的lambda应该不那么简单。你需要的是一种编译时检查的从类型C的对象到类型T的值的方法。在Java中指定它的方式是一个接口:
public interface Getter<C, T> {
T get(C c);
}
然后将您的功能指定为
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; }
});
Java8的lambda将使这个更具可读性:
foo(a1, a2, a -> a.fieldName);