简体   繁体   English

使用反射来迭代类成员

[英]Use reflection to iterate over class members

I have a class with numerous parameters of various types. 我有一个包含各种类型参数的类。 I want to iterate over all type A members , and run a specific functions ( A.doSomething() ) 我想迭代所有类型的A成员,并运行一个特定的函数(A.doSomething())

This doesn't even compile: The conversion from field to XPathDataElement is illegal 这甚至不编译:从字段到XPathDataElement的转换是非法的

Field[] fields = this.getClass().getDeclaredFields();
  for (Field field : fields) {
     if (field. getType().getName().equals(XPathDataElement.class.getName()))
        {               
                tmp = (XPathDataElement)field; // Doesn't compile
                sb.append(field.getName() + ":"); 
                tmp.update();
        }
    }

Thanks! 谢谢!

It's hard to debug your code when you don't say what's wrong with it. 当你没有说出它的错误时,很难调试你的代码。

Two things I can see: 我能看到的两件事:

  1. There's no need to compare strings to decide if the field's type is the right class. 没有必要比较字符串来确定字段的类型是否是正确的类。

     if (field.getType().equals(XPathDataElement.class)) 

    should work. 应该管用。

    Edit: Steve Reed points out that you don't necessarily need it to be exactly XPathDataElement ; 编辑: XPathDataElement 指出 ,你不一定需要它完全是XPathDataElement ; a subclass will work just as well. 子类也可以正常工作。 To check if the field can be treated as an XPathDataElement , you should use Class.isAssignableFrom(Class) . 要检查该字段是否可以视为XPathDataElement ,您应该使用Class.isAssignableFrom(Class)

     if (XPathDataElement.class.isAssignableFrom(field.getType())) 

    would be the code. 将是代码。

  2. I guess your real question is how to get the value of a field reflectively? 我想你真正的问题是如何反思地得到一个领域的价值? If so, then Field.get(Object) is what you want. 如果是这样,那么Field.get(Object)就是你想要的。 The object that you pass to get() is the one whose field you want to retrieve; 传递给get()的对象是您要检索其字段的对象; if you're operating on this (which is a strong code smell), then your code would be 如果你在运行this (这是一个强大的代码味道),那么你的代码将是

     XPathDataElement tmp = (XPathDataElement) field.get(this); 

I strongly suggest avoiding reflection unless you really need it. 我强烈建议避免反思,除非你真的需要它。

Just write the code out: 只需编写代码:

this.x.doSomething();
this.y.doSomething();
this.z.doSomething();

Or if you like: 或者如果你喜欢:

for (A a : new A[] {
    this.x, this.y, this.z
}) {
    a.doSomething();
}

A couple of pointers: 几个指针:

  1. Compare the classes for equality, not their names. 比较类的相等性,而不是它们的名称。

    field.getType().equals(XPathDataElement.class) field.getType()。等于(XPathDataElement.class)

  2. Or better yet, use isAssignableFrom(java.lang.Class) to handle the case where the class declares a return type as a sublclass of what you're looking for 或者更好的是,使用isAssignableFrom(java.lang.Class)来处理类声明返回类型作为您要查找的子类的情况

    XPathDataElement.class.isAssignableFrom(field.getType()) XPathDataElement.class.isAssignableFrom(field.getType())

  3. You're iterating over fields , not method . 你是在迭代字段而不是方法 Your question leads me to assume you want the latter, and if so, use: 你的问题让我假设你想要后者,如果是,请使用:

    this.getClass().getDeclaredMethods() this.getClass()。getDeclaredMethods()

You don't seem to assign anything to the obj that you cast to XPathDataElement in the loop. 您似乎没有为在循环中XPathDataElementXPathDataElementobj分配任何内容。

You probably want to do something like this: 你可能想做这样的事情:

tmp = (XPathDataElement)field.get(this);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM