在javascript中,我可以这样做:
function MyObject(obj) {
for (var property in obj) {
this[property] = obj[property];
}
}
我可以用Java做点什么吗?
class MyObject {
String myProperty;
public MyObject(HashMap<String, String> props) {
// for each key in props where the key is also the name of
// a property in MyObject, can I assign the value to this.[key]?
}
}
答案 0 :(得分:3)
这些答案都很糟糕,所以我想帮个忙,增加一个体面的答案。首先,我会尽可能使用地图 :
private List<String> getAllAyaFromSuraIndex(String suraIndex) {
List<String> list = new ArrayList<>();
XmlPullParser parser = getResources().getXml(R.xml.quran_arabic);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("sura")) {
String index = parser.getAttributeValue(0);
// Match given sure index
if (index.equals(suraIndex)) {
// Move to first aya tag inside matched sura index
parser.next();
// This loop will exit when it reaches sura end tag </sura>
while (parser.getName().equals("aya")) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
list.add(parser.getAttributeValue(0) + ".\n" + parser.getAttributeValue(1));
}
// Move to next aya tag
parser.next();
}
break;
}
}
parser.next();
}
return list;
}
但是假设您要动态设置字段。
class MyObject {
// String myProperty; // ! not this
HashMap<String,String> myProperties; // use this instead
}
当然,您将需要在上述构造函数中使用try / catch。
答案 1 :(得分:2)
是的,你可以通过以下几点的反思来做到这一点:
/**
* Returns a list of all Fields in this object, including inherited fields.
*/
private List<Field> getFields() {
List<Field> list = new ArrayList<Field>();
getFields(list, getClass());
return list;
}
/**
* Adds the fields of the provided class to the List of Fields.
* Recursively adds Fields also from super classes.
*/
private List<Field> getFields(List<Field> list, Class<?> startClass) {
for (Field field : startClass.getDeclaredFields()) {
list.add(field);
}
Class<?> superClass = startClass.getSuperclass();
if(!superClass.equals(Object.class)) {
getFields(list, superClass);
}
}
public void setParameters(Map<String, String> props) throws IllegalArgumentException, IllegalAccessException {
for(Field field : getFields()) {
if (props.containsKey(field.getName())) {
boolean prevAccessible = field.isAccessible();
if (!prevAccessible) {
/*
* You're not allowed to modify this field.
* So first, you modify it to make it modifiable.
*/
field.setAccessible(true);
}
field.set(this, props.get(field.getName()));
/* Restore the mess you made */
field.setAccessible(prevAccessible);
}
}
}
但是,如果您对Java不是很熟悉,那么应该尽可能避免这种方法,因为它有点危险并且容易出错。例如,无法保证您尝试设置的Field
实际上是期望一个字符串。如果不是这样,您的程序将崩溃并烧毁。
答案 2 :(得分:2)
并非我不同意Joel的回答,但如果您基本上只是想要尽力而为,我认为这并不是那么困难。基本上检查它是否存在,以及是否尝试设置。如果它工作得很好,哦,我们尝试过。例如:
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class MyObject {
protected String lorem;
protected String ipsum;
protected int integer;
public MyObject(Map<String, Object> valueMap){
for (String key : valueMap.keySet()){
setField(key, valueMap.get(key));
}
}
private void setField(String fieldName, Object value) {
Field field;
try {
field = getClass().getDeclaredField(fieldName);
field.set(this, value);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Map<String, Object> valueMap = new HashMap<String, Object>();
valueMap.put("lorem", "lorem Value");
valueMap.put("ipsum", "ipsum Value");
valueMap.put("integer", 100);
valueMap.put("notThere", "Nope");
MyObject f = new MyObject(valueMap);
System.out.println("lorem => '"+f.lorem+"'");
System.out.println("ipsum => '"+f.ipsum+"'");
System.out.println("integer => '"+f.integer+"'");
}
}
答案 3 :(得分:1)
好吧,如果你真的想要反思raod,那么我建议你看一下Introspector类,并从BeanInfo中获取属性描述符列表。