web-dev-qa-db-fra.com

Comment utiliser getConstructor (params) .newInstance (args)?

Cela pourrait bien être une question stupide, mais je suis nouveau sur Java, alors ...

J'ai actuellement du code où il est actuellement utilisé clazz.asSubclass(asSubclassOfClass).getConstructor().newInstance()

J'ai besoin de passer quelques arguments au contructort donc je veux le changer en: clazz.asSubclass(asSubclassOfClass).getConstructor(params).newInstance(args)

Ce que je ne comprends pas, c'est ce que je dois transmettre sous la forme params et ce que je dois transmettre sous la forme args.

Disons que je voulais passer une chaîne "howdy" et un objet de type XYZ appelé XyzObj. Comment pourrais-je spécifier cela? Que devrais-je passer en tant que params et que devrais-je passer en arguments?

27
Eli

En Java cela s'appelle Réflexion .

En supposant que la classe a ce constructeur, sinon vous obtiendrez une exception NoSuchMethod je crois.

clazz.asSubclass(asSubclassOfClass)
    .getConstructor(String.class,XYZ.class)
    .newInstance("howdy",XyzObj);

Étant donné que vous êtes nouveau sur Java, permettez-moi de vous donner un moyen plus facile afin que vous puissiez comprendre ce qui se passe sous le capot lorsque vous faites cela.

Supposons que vous ayez la classe suivante:

public class ParentClazz{
        String someVar;
    public ParentClazz(){
        someVar="test";
    }
    public ParentClazz(String someVar){
        System.out.println("I have been invoked");
        this.someVar=someVar;
    }
}

Ensuite, vous avez la méthode principale suivante:

public static void main(String[] args) throws ParseException, IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
           ParentClazz.class.asSubclass(ParentClazz.class).getConstructor(String.class).newInstance("howdy");
    }

Si vous exécutez cela, vous remarquerez le message d'impression de sortie de la console - J'ai été invoqué. Cela signifie qu'en utilisant la réflexion, vous avez invoqué le constructeur de ParentClazz.

Vous pouvez faire la même chose si le scénario vous le permet en utilisant le processus de création d'objet standard:

ParentClazz clazz = new ParentClazz("howdy");

J'espère que cela vous aidera à le comprendre.

45
CoolBeans

Voici un exemple de création de classes sans le nouveau mot-clé. Les classes prennent d'autres classes à la fois des primitives et des objets comme paramètres. L'exemple montre également l'instance d'une sous-classe et d'une classe parent en cours de création

public class ConstructorInstantiateWithoutNew 
{
    @SuppressWarnings("rawtypes")
    public static void main( String [] args )
    {
        Class<Drinker> clazz_drinker = Drinker.class;
        Class [] paramTypes = { Fizz.class, Colour.class, int.class };
        Object [] paramValues = {  new Fizz(), new Colour(), new Integer(10) };

        Class<Drunk> clazz_drunk = Drunk.class;
        Class [] paramTypesSub = { Fizz.class, Colour.class, int.class, boolean.class };
        Object [] paramValuesSub = {  new Fizz(), new Colour(), new Integer(10), true };

        try 
        {
            Drinker drinker = clazz_drinker.getConstructor( paramTypes ).newInstance( paramValues );
            drinker.drink();

            Drunk drunk = clazz_drunk.getConstructor(paramTypesSub).newInstance(paramValuesSub);
            drunk.drink();
        }
        catch (Exception e) 
        {
            e.printStackTrace();
        } 
    }
}

class Drinker
{
    int n;

    public Drinker( Fizz f, Colour c, int n)
    {
        this.n = n;
    }

    public void drink()
    {
        System.out.println( "Dad drank " + (n*10) + " ml");
    }
}

class Drunk extends Drinker
{
    boolean trouble;
    public Drunk(Fizz f, Colour c, int n, boolean inDogHouse)
    {
        super(f,c,n);
        trouble = inDogHouse;
    }

    public void drink()
    {
        System.out.println( 
                "Dad is Grounded: " + trouble + 
                " as he drank over "+ 
                (n*10) + " ml");
    }
}

class Fizz {} class Colour {}

J'espère que c'est utile

Sincères amitiés

Naresh Maharaj

5
Naresh Maharaj
clazz.asSubclass(asSubclassOfClass)
     .getConstructor(String.class, XYZ.class)
     .newInstance("howdy", XyzObj)

Qui suppose que les arguments du constructeur sont dans l'ordre spécifié

3
Kevin Welker