java如何将一个类中声明的所有字符串常量及其内部类放在一个键集中
可能隐藏的问题是,对于具有某种层次结构的键,应该使用哪种结构(因此,我尝试使用类和内部类,以便可以对特定子集进行测试)。我正在寻找一种结构,在这种结构中,我可以在适当的位置添加一个新的键,并自动将该键放入适当的键集中。下面是我的实际尝试: 现在,我使用键作为静态最终字符串和相应的键集。 我经常需要测试某个键是否包含在其他类中声明的一组键(公共静态最终字符串)中。 因此,我从一个Keys1类扩展了所有具有键的类,该类有一个方法keySet(),该方法给出了键集。很好
public class Keys1
{
private TreeSet<String> m_keySet = new TreeSet<String>();
public Keys1()
{
initKeySet();
}
private void initKeySet()
{
Field[] felder = this.getClass().getFields();
for (Field f : felder)
{
if (Modifier.isFinal(f.getModifiers()))
{
try
{
if (f.get(f) instanceof String)
{
m_keySet.add(f.get(f).toString());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
public TreeSet<String> keySet()
{
return m_keySet;
}
}
现在,我试图在Keys2类中编写一个类似的功能,其中keySet还应该包含在Keys2类型的内部类中声明的键,但没有成功
public class Keys2 extends Keys1
{
@Override
protected void initKeySet()
{
super.initKeySet();
Class<?>[] innerClasses = this.getClass().getDeclaredClasses();
for (Class<?> innerClass : innerClasses )
{
if (innerClass.getClass().isInstance(Keys1.class))
{
Keys1 newKeys;
try
{
newKeys = (Keys1) innerClass.newInstance(); // Doesn't work
keySet().addAll(newKeys.keySet());
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
}
}
}
# 1 楼答案
既然您说过,您只在寻找
public static final String
字段,那么您正在做不必要的工作。您没有筛选字段以仅访问static
字段,而且,您正在查询字段并检查结果的类型,而不是首先检查字段的类型此外,检索
static
字段不需要对象实例。如果代码是在Class
上运行的,那么它可以用来处理发现的内部类,而无需实例化它们由于此过程不需要对象实例,因此也没有理由对每个实例重复该操作,也没有理由将结果存储在实例字段中。你只需要记住每个类的结果,谢天谢地,有一个名为^{} 的类免费提供了这个结果
把它放在一起,你就可以实现它
{}负责缓存。调用
get
时,它会检查指定类是否已经有计算值,否则,它会调用computeValue
。这个解决方案中的computeValue
方法利用它本身来处理超类字段,因此如果您为不同的子类调用它,它们将共享公共基类的结果,而不是重复工作子类在这里不需要做任何事情,继承的
keySet()
方法就足够了,因为它使用getClass()
,返回实际的类如图ideone demo所示
当您在Java 7之前的Java版本中运行时,可以使用下面的ersatz,当您迁移到新的Java版本时,应该立即用真实的东西替换它
解决方案本身所需的唯一变化是替换菱形操作符使用
new TreeSet<>()
与显式类型的new TreeSet<String>()
。然后,它应该在Java6中工作