我需要动态JTree,其中节点将是对象,当节点扩展时,我将使用反射来获取声明的字段。所有非原始字段都将是节点,依此类推,递归。
所以这是我的TreeNode类的简短描述:
public TreeNode(Object o){
this.name = o.getClass().getSimpleName();
this.treeobjectclass = o.getClass();
this.isbranch = isBranchObject();
this.properties = initializePropertiesMap();
this.children = //here i will get children with getDeclared fields and
//instantiate new TreeNode for nonprimitive ones
}
问题:
当通过子进行递归实例化时,如果遇到其构造函数要求参数的子类之一,如何避免出现问题?
我是否应该将Class参数而不是Object传递给构造函数?
如何摆脱这个被诅咒的循环?我是全新的反思。有类似工作的例子吗?
谢谢
答案 0 :(得分:1)
我认为这看起来不像反射的典型用例。无论如何,试着回答你的问题:
您可以使用ctor.setAccessible(true)
启用默认构造函数,无论它是否为私有构造函数,并使用例如clazz.newInstance()
对其进行实例化。如果它是不存在的,那么你将进入构造函数参数的猜测游戏或sun.misc.Unsafe.allocateInstance(clazz)
,这两者都不是优先考虑的。
你正在使用它,它看起来应该足够用类引用。传递一个物体意味着它被使用了,但事实并非如此。
如果你只需要传递一个对象来获取它的构造函数参数,那么我会说你最好为该对象传递factory以避免完全反射。这也是Oracle Secure Coding Guideline的建议。
传递工厂的一个修改是让你想要实例化的每个类都提供自己的工厂逻辑,例如,
interface FactoryProvider<T> {
public T getInstance();
}
class Concrete implements FactoryProvider<Concrete> {
@Override
public Concrete getInstance() {
return new Concrete();
}
}
但话又说回来,如果您完全控制以这种方式创建的所有对象的源代码,您可以自己强制执行它们都具有默认构造函数。