我有许多类,可以包含TranslatableText
类型的一个或多个属性。此外,某些类可能具有自身包含此类属性的属性,例如List<TranslatableText>
或Map<String, TranslatableText>
。
您将如何以有效的方式扫描这些类,同时在通用集合中获取TranslatableText
的实例?
class Project{
String id;
TranslatableText name;
List<Action> actions;
}
class Action {
String id;
TranslatableText name;
TranslatableText description;
}
// getter & setters omitted
答案 0 :(得分:2)
你可以使用像这样的循环
// for super classes, use recursion.
for(Field f : obj.getClass().getDeclaredFields()) {
Class type = f.getType();
if (type == String.class || type == TranslatableText.class) {
Object value = f.get(object);
if (value != null)
map.put(f.getName(), value.toString());
}
答案 1 :(得分:0)
感谢Peter Lawrey最初的想法。这对我来说是有效的(到目前为止)。我不得不避免循环递归,这就是我添加visited
列表的原因。扫描Arrays
,Collections
和Maps
,这对我来说已经足够了。
/**
* Examine class members for TranslatableTexts. Traverse down into
* properties including Collections and Maps but ignoring java.lang classes
*
* @param obj
* @return
*/
public static Collection<? extends TranslatableText> getTranslatables(
Object obj, List<Object> visited)
{
List<TranslatableText> result = new ArrayList<TranslatableText>();
if (obj instanceof TranslatableText)
{
result.add((TranslatableText) obj);
return result;
}
if(visited.contains(obj))
return result;
visited.add(obj);
for (Field f : obj.getClass().getDeclaredFields())
{
f.setAccessible(true);
Class type = f.getType();
if (type.isPrimitive() == false
&& (type.getPackage() == null || type.getPackage()
.getName().startsWith("java.lang") == false))
{
try
{
Object value = f.get(obj);
if (value != null)
{
if (type.isArray())
{
Class arraytype = type.getComponentType();
if (arraytype == TranslatableText.class)
{
TranslatableText[] tt = (TranslatableText[]) value;
if (tt != null)
{
for (TranslatableText t : tt)
{
result.add(t);
}
}
}
}
else if (type == TranslatableText.class)
{
TranslatableText tt = (TranslatableText) value;
if (tt != null)
result.add(tt);
}
else if (value instanceof Collection)
{
for (Object o : (Collection<?>) value)
{
result.addAll(getTranslatables(o, visited));
}
}
else if (value instanceof Map)
{
for (Object o : ((Map) value).values())
{
result.addAll(getTranslatables(o, visited));
}
}
else
{
result.addAll(getTranslatables(value, visited));
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
return result;
}