2010-12-16 55 views
1

拿这个代码,例如:Constructor.newInstance()不知道参数序列?

public class User { 
    private String username; 
    private String password; 

    protected User() 
    {} 

    public User(String username , String password) 
    {...} 

    //getters & setters 
} 

我们可以用User.class.getConstructors(),发现有2名建设者,并与constructor.getParameterTypes(),我们可以找出有一个构造函数有两个字符串参数。 我们也可以使用反射来查找两个属性:用户名和密码。 但是,在运行时,我们不知道用于调用constructor.newInstance(?,?)的两个参数的正确顺序。

constructor.newInstance(username , password)constructor.newInstance(password , username)都是合法的,但结果完全不同。

我不能使用User.class.newInstance()并设置属性值,因为no-arg构造函数是受保护的。

我遇到这个问题,因为我想写一个通用的JPA CRUD工具。列表/读取/更新/删除都可以。但现在我面临的问题是我无法在线创建对象。实体类都有一个受保护的无参数构造函数(所以我不能使用class.newInstance())和一个参数很多的公共构造函数(但参数名称在运行时会被擦除)。

如何做到这一点? javassist或其他代理技术是否有帮助?怎么样 ? 非常感谢!

回答

3

您可以使用:

Constructor<?> c = class.getDeclaredConstructor(); 
c.setAccessible(true); 
c.newInstance(); 

这就是JPA会做,无论如何,因为它通过它们的无参数构造函数实例化对象。

+0

哇,谢谢你告诉我,我可以修改保护公开。我以前不知道JVM允许这样做。 – smallufo 2010-12-16 15:06:42

+1

我不会为了实现它而修改一个类,因为这种修改的后果不容易预见。这就是所谓的“黑客”:) – 2010-12-16 15:06:49

+1

它没有修改它。它只是使其可以暂时访问 – Bozho 2010-12-16 15:10:32

1

这可能只是一个解决办法,但使用不能创建用户(我省略反射的可读性的目的)

User u = new User(null, null); 

,然后设置你的工具的属性?

u.setUsername(...); 
u.setPassword(...); 

您可以生成代码,或多或少原子,所以它不会不管你

0

虽然订单在运行时是相同的,但为什么不直接找出正确的顺序,并将其视为如此。