2010-12-16 3 views
1

Nehmen Sie diesen Code zum Beispiel:Constructor.newInstance() ohne die Parametersequenz zu kennen?

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

    protected User() 
    {} 

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

    //getters & setters 
} 

Wir User.class.getConstructors() und dort 2 Konstrukteure finden können sind, und mit constructor.getParameterTypes() können wir identifizieren es mit zwei String-Parameter einen Konstruktor ist. Wir können Reflection auch verwenden, um zwei Eigenschaften zu finden: Benutzername und Passwort. Aber, zur Laufzeit, wir kennen nicht die richtige Reihenfolge der beiden Parameter verwendet werden, um constructor.newInstance (?,?) Aufzurufen.

constructor.newInstance(username , password) und constructor.newInstance(password , username) sind beide legal, aber mit völlig anderen Ergebnissen.

Ich kann User.class.newInstance() nicht verwenden und Eigenschaftswert festlegen, da der NO-Arg-Konstruktor geschützt ist.

Ich stoße auf dieses Problem, weil ich versuche, ein generisches JPA CRUD-Tool zu schreiben. Liste/Lesen/Aktualisieren/Löschen sind in Ordnung. Aber jetzt habe ich das Problem, dass ich kein Objekt online erstellen kann. Die Entity-Klassen haben alle einen geschützten No-Arg-Konstruktor (also kann ich class.newInstance() nicht verwenden) und einen öffentlichen A-Lot-of-Parameter-Konstruktor (aber die Parameternamen werden zur Laufzeit gelöscht).

Wie geht das? Können Javassist oder andere Proxy-Techniken helfen? Wie ? Vielen Dank!

Antwort

3

können Sie verwenden:

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

dass das, was JPA ist sowieso tun wird, weil es instanziiert Objekte über ihren Nicht-Arg-Konstruktor.

+0

Wow, danke, dass du mir gesagt hast, dass ich geschützt für die Öffentlichkeit modifizieren kann. Ich wusste nicht, dass JVM das vorher erlaubt. – smallufo

+1

Ich würde eine Klasse nicht modifizieren, um sie instanziieren zu können, da die Konsequenzen dieser Änderung nicht leicht vorhersehbar sind. Das nennt man einen "Hack" :) –

+1

es wird nicht geändert. Es wird nur temporär zugänglich gemacht – Bozho

1

Das ist nur eine Abhilfe sein könnte, aber könnten Sie den Benutzer nicht erstellen mit (Ich lasse Reflexion zum Zwecke der besseren Lesbarkeit)

User u = new User(null, null); 

und dann legen Sie die Eigenschaften in Ihrem Werkzeug?

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

Sie Code generieren könnte, die mehr oder weniger Atom ist, so ist es dir egal wäre

0

Die Reihenfolge wird zur Laufzeit identisch sein, also warum nicht einfach die richtige Reihenfolge herausfinden und sie so behandeln.