2013-06-18 40 views
0

很抱歉的标题...反射有帮助吗?

我有类似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的是真正的一个领域反对
  • 我想避免需要重复.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) { 
    } 
} 

,但我不能在编译时检查,如果字段名是一个有效的字段名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); 

感谢您的任何答案,卡罗

+0

myField和anotherField是否返回相同的类型?或者他们返回什么类型? – Damian0o

+0

myField和另一个字段是相同的类型(否则我得到一个编译错误),但我想避免这种情况。我想FLD1和FLD2是同一类 – Carlo

回答

2

你可以做检查在运行时使用方法instanceOf

刚刚例如:

if(fd1 instanceOf Fd1Obj) 
2

我想,以确保在编译的时候..

反思是所有关于运行。 因此,编译时间没有帮助。

+0

我知道的两种不同情况下的同场,但也许它可以帮助不编译时间,但检查约束 – Carlo

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); 
+1

'延伸Object'是有点画蛇添足...... –

+0

很抱歉,但我不明白。 FLD1和FLD2各字段,所以我不能做'fld1.getClass()。getfield命令(“MyField的”)'在类FLD1的不存在“MyField的”字段。 – Carlo

+0

我改变了我的问题,提出一些建议,这样你就能明白为什么它不是我的答案。 – Carlo

0

您可以指定类型调用时foo(..)like:

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

这样就可以确定类型检查是在编译时完成的。

然而,这不是强制性的,如果你不提供,即在这种情况下,类型参数,Java文档说:

推理算法试图找到最具体类型 作品与所有的论据。

看看这里:

http://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

且无反射不会对编译时检查帮助好。

+0

我想我的问题是不够清楚......把foo()方法是静态的,并没有涉及到具体的类。 – Carlo

+0

静态方法属于一类,而不是任何特定的实例。所以当你调用它时,你可以提供类型参数。我希望我能得到你。 – hakish

+0

很抱歉,但...我想FLD1和FLD2是同一类的(但我不知道,我不在乎它是类) – Carlo

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); 
+0

由于两个不同的实例的同场!是的,它是冗长的! – Carlo