smallufo
smallufo

Reputation: 11796

Constructor.newInstance() without knowing parameter sequence?

Take this code for example :

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

  protected User()
  {}

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

  //getters & setters
}

We can use User.class.getConstructors() and find there are 2 constructors , and with constructor.getParameterTypes() , we can identify there's one constructor with two String parameters. We can also use reflection to find two properties : username and password. But , at run time , we don't know the proper sequence of the two parameters being used to call constructor.newInstance(?,?).

constructor.newInstance(username , password) , and constructor.newInstance(password , username) are both legal but with totally different result.

I cannot use User.class.newInstance() and set property value because the no-arg constructor is protected.

I encounter this problem because I am trying to write a generic JPA CRUD tool. List/Read/Update/Delete are OK. But now I face the problem that I cannot online create an object. The entity classes are all with a protected no-arg constructor (so I cannot use class.newInstance()) , and one a-lot-of-parameter public constructor (but the parameter names are erased at runtime).

How to do this ? Does javassist or other proxy-techniques help ? how ? Thanks a lot !

Upvotes: 1

Views: 1961

Answers (3)

Lukas Eder
Lukas Eder

Reputation: 220877

That might be just a workaround, but couldn't you create the User using (I omit reflection for the purpose of readability)

User u = new User(null, null);

and then set the properties in your tool?

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

You could generate code that is more or less atomic, so it wouldn't matter to you

Upvotes: 1

Samuel Parsonage
Samuel Parsonage

Reputation: 3127

The order will be the same at runtime though, so why not just figure out the correct order, and treat it as such.

Upvotes: 0

Bozho
Bozho

Reputation: 597106

You can use:

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

That's what JPA will do anyway, because it instantiates objects via their no-arg constructor.

Upvotes: 3

Related Questions