Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中迭代成员变量_Java_Oop_Variables_Iterator_Hashmap - Fatal编程技术网

在Java中迭代成员变量

在Java中迭代成员变量,java,oop,variables,iterator,hashmap,Java,Oop,Variables,Iterator,Hashmap,我有几种情况,其中一个类由任意(但固定)数量的不同类型的变量组成,并且希望迭代这些变量,并在代码中使用它们的名称。有没有比在每个函数中重新键入每个变量名更聪明的方法 我最初的想法是使用HashMap来存储局部变量,但这似乎效率低下,而且不能处理多种类型 模拟以下代码以缩短所需的读数,但其变量通常超过3个: class Widget implements Parcelable { String name, code; Long price; public void wri

我有几种情况,其中一个类由任意(但固定)数量的不同类型的变量组成,并且希望迭代这些变量,并在代码中使用它们的名称。有没有比在每个函数中重新键入每个变量名更聪明的方法

我最初的想法是使用HashMap来存储局部变量,但这似乎效率低下,而且不能处理多种类型

模拟以下代码以缩短所需的读数,但其变量通常超过3个:

class Widget implements Parcelable {
    String name, code;
    Long price;

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(code);
        dest.writeLong(price);
    }

    public Widget(Parcel o) {
        name = o.name;
        code = o.code;
        price = o.price;
    }

    public String getXML() {
        return "<Widget><name>"+name+"</name><code>"+code
              +"</code><price>"+price+"</price></Widget>";
    }
}
相反,我更喜欢做(伪代码):


如果有许多类的代码遵循相同的模式,我将编写一个代码生成器,从某种定义文件生成Java源代码。然后,您可以让生成器创建与第一个示例类似的简单代码,这比使用通用映射或反射等更容易阅读和理解。定义文件将成为每种对象字段的“官方”源

由于您已经熟悉Python,您的定义文件可以直接构建到Python脚本中以创建源代码。例如:

Objects = {
    "Widget": [
        (TYPE_STRING, "name"),
        (TYPE_STRING, "code"),
        (TYPE_LONG, "price"),
    ],
    # ...
}

通过对
类型\u字符串
等的适当定义,编写一些代码从中生成Java源代码应该很简单。

通常通过反射解决:

for (Field f : getClass().getDeclaredFields()) {
    String name = f.getName();
    String value = f.get(this);
}
但是,对于XML的写入/读取,您可能希望使用而不是重新发明轮子

使用Jackson:

序列化与JSON序列化非常相似:只需更改ObjectMapper实例即可使用:

// Important: create XmlMapper; it will use proper factories, workarounds
ObjectMapper xmlMapper = new XmlMapper();
String xml = xmlMapper.writeValue(new Simple());
和POJO一样:

public class Simple {
    public int x = 1;
    public int y = 2;
}
你会得到如下结果:

<Simple>
  <x>1</x>
  <y>2</y>
</Simple>

1.
2.
(除非默认情况下输出不缩进:可以使用标准Jackson机制启用缩进)

从XML反序列化POJO 与序列化类似,反序列化与JSON反序列化没有太大区别:

ObjectMapper xmlMapper = new XmlMapper();
Simple value = xmlMapper
   .readValue("<Simple><x>1</x><y>2</y></Simple>", Simple.class);
ObjectMapper xmlMapper=new xmlMapper();
简单值=xmlMapper
.readValue(“12”,简单类);
另外,您还可以使用反射,并使用
Class.getDeclaredFields()
通过所有声明的字段进行迭代。但根据我的经验,很少有人需要这样做。有很多第三方开源库用于不同的目的,通常使用它们是更好的解决方案(例如,在这个特殊情况下使用Jackson)

我认为这是最简单的框架。参考答案,你会有一个想法

它只需创建一个映射类,例如带有所有成员属性和对象可能嵌套的
小部件
,然后调用:

   XStream xstream = new XStream(new DomDriver());
   String xml = xstream.toXML(widgetObject);  // <-- Get XML String from object

   Widget widget = (Widget)xstream.fromXML(xml); //<-- Get object from XML
XStream XStream=newxstream(newdomdriver());

字符串xml=xstream.toXML(widgetObject);//理想情况下,如果你的类中有这么多的变量,你应该移动ValueObject中的相关变量,并在类中使用它的引用。因为你正在访问成员变量(而不是像你原来的标题那样的局部变量),你可以使用反射来访问它们。有关更多详细信息,请查看反射API和教程。或者,您可以将这些值重构为另一个类,并使用继承或组合来重用代码。您根本不必处理手工构建XML的问题。@EugeneRetunsky:为什么是Jackson而不是JAXB?@HovercraftFullOfEels这是我个人的偏好。依我看,它使用起来更简单。而且它的应用也很广泛。XML我故意把它写成一个字符串,以避免特定的API,并给出任何我可以快速键入的示例。+1虽然我花了一些时间阅读Java反射,但看起来几乎完美。。。虽然这可能需要一些时间来正确地吸收。我可以用这个方法管理大多数情况,其中我在一个对象中列出了许多变量,但到目前为止从SQLite游标填充的情况除外。没有通用的Cursor.getObject(…)可以为f.set(…)强制转换;也许还有另一个问题是必要的。呃,为了映射数据库行,我想让您看看……w.r.t。JPA,这个问题是一般性的,但对我来说,实现是特定于Android的,尽管看起来很有趣。这不是简单地从变量中提取XML,而是在多个类函数中反复迭代局部变量。我喜欢这是一种黑客行为,但感觉像是一种黑客行为。我怀疑@meriton所建议的反思最符合我的目的。如果我找到了一个好的解决方案,我保证会发布一个有效的例子。
ObjectMapper xmlMapper = new XmlMapper();
Simple value = xmlMapper
   .readValue("<Simple><x>1</x><y>2</y></Simple>", Simple.class);
   XStream xstream = new XStream(new DomDriver());
   String xml = xstream.toXML(widgetObject);  // <-- Get XML String from object

   Widget widget = (Widget)xstream.fromXML(xml); //<-- Get object from XML