web-dev-qa-db-fra.com

Comment accéder à une méthode statique via une référence de classe

class A {
    public static void foo() {}
}

class B {
    public static void foo() {}
}

J'ai Class clazz = A.class; or B.class;

Comment puis-je accéder à cela via "clazz" en supposant qu'il soit attribué "A" ou "B"

20
user339108

Il est uniquement possible d'accéder à ces méthodes en utilisant la réflexion. Vous ne pouvez pas référencer directement une classe, mais seulement une instance de type Class.

Pour utiliser la réflexion pour appeler methodname (int a, String b):

Method m = clazz.getMethod("methodname", Integer.class, String.class);
m.invoke(null, 1, "Hello World!");

Voir Class.getMethod () et Method.invoke ()

Vous voudrez peut-être repenser votre conception afin d'éviter d'avoir à appeler dynamiquement des méthodes statiques.

32

Vous pouvez invoquer une méthode statique par réflexion comme ceci:

Method method = clazz.getMethod("methodname", argstype);
Object o = method.invoke(null, args);

Où argstype est un tableau d'arguments type et args est un tableau de paramètres pour l'appel. Plus d'informations sur les liens suivants: 

Dans votre cas, quelque chose comme ceci devrait marcher:

Method method = clazz.getMethod("foo", null);
method.invoke(null, null); // foo returns nothing
10
krtek

Vous ne pouvez pas accéder à des méthodes statiques sans une référence explicite à la classe.

Pas d'héritage ici, désolé, vous devez donc faire:

A.foo()

ou

B.foo()

Si vous en avez vraiment besoin, vous devrez vérifier:

Object o = .... // eith an A or B instance.
if( o instanceof A ) {
    A.foo()
} else {
    B.foo()
}

Mais pourquoi ne faites-vous pas ces fonctions comme des fonctions et les laissez-vous implémenter dans une interface?

Okey, vous avez un objet de classe. Alors fais:

Class c = ...;
c.getMethod("foo").invoke(null); // null to invoke static methods
5
Daniel

J'espère que cela ne fait pas trop d'hypothèses ou ne s'écarte trop de votre question, mais si vos deux classes partagent un supertype commun et que la création d'une instance est tolérable, vous pouvez:

  1. Mettre en place une interface commune
  2. Créez une instance de l'objet via myClass.newInstance() (la classe doit avoir un constructeur vide)
  3. Appelez la méthode statique à partir de l'objet d'instance.


interface Foo {
    void foo();
}
class A implements Foo {...}
class B implements Foo {...}

<T extends Foo> public void something(Class<T> clazz) {
    T myInstance = clazz.newInstance();
    myInstance.foo();
}

...
something(A.class);

C'est un peu bizarre, mais dans mon cas, cela s'est avéré utile et j'ai commencé par poser la même question que vous avez posée.

1
geg

Selon mon manque de connaissances, le besoin de la construction demandée est donné par le fait qu'une interface n'offre pas la possibilité de méthodes abstraites statiques. Voici un exemple:

public enum Cheese implements Yumy {
  GOUDA(49),
  ESROM(40),
  HWARTI(38);
  private int percentage;
  private Cheese(int fat100) {...} constructor
  public void yamyam() {...} // as in Yumy
  public static Cheese getByFat(int fat100) {...} // no chance to be part
                                                     of interface
};
1
Vollbracht