18 votes

Appel d'une méthode statique à l'aide d'un type générique

Aucun membre statique ne peut utiliser un paramètre de type, mais est-il possible d'appeler un membre statique en utilisant le paramètre de type générique ? Par exemple:-

abstract class Agent<A>{
    void callAgent();
    Agent(){
        A.add();                    
    }
}

Ici, add() est une méthode statique.

Il y a quelques questions et réponses en C# sur un sujet similaire mais je ne sais pas trop comment procéder en Java.

9voto

Bozho Points 273663

Non, vous ne pouvez pas. Le compilateur ne sait pas A (qui se résout en Object ) possède la méthode add.

Et vous ne devriez pas avoir besoin d'invoquer des méthodes statiques sur des types génériques en premier lieu. Si vous souhaitez un comportement spécifique pour chaque type, définissez-le comme non statique, utilisez la méthode extends BaseClass dans la déclaration générique, et l'invoquer.

Techniquement, vous pouvez aussi invoquer une méthode statique de cette manière, mais c'est moche :

class Base {
    public static void add() { }
}

class Foo<A extends Base> {
    void bar() {
        A a = null; // you can't use new A()!
        a.add();
    }
}

9voto

Adam Gent Points 15055

Non, vous ne pouvez pas le faire si A est un type générique. (Bozho a répondu trop vite :) et a probablement pensé que A était un type concret.

Ce qui fonctionnera, c'est ce qui suit.

abstract class Agent extends Blah<ConcreteA>{
    void callAgent();
    Agent() {
        ConcreteA.add();
    }
}

mais ce n'est probablement pas ce que vous voulez faire.

Après avoir lu vos commentaires, il semble que ce que vous voulez vraiment faire, c'est.. :

abstract class Agent<A extends SomeClassThatSupportsAdd> {

    void callAgent();
    protected abstract A createNew();

    Agent() {
        A a = createNew();
        A.add();
    }
}

Vos sous-classes devront surcharger createNew() .

Si vous n'aimez toujours pas cela, vous pouvez jeter un coup d'œil à AspectJ qui vous permettra de faire un peu de magie avec les constructeurs (voir comment Spring fait @Configurable), mais cela devient beaucoup plus délicat et complique les choses.

Une autre option est Scala. Java ne fait pas d'héritage sur les méthodes statiques, vous ne pouvez donc pas obtenir de modules paramétrés (groupes de fonctions dans certains langages, cela s'appelle un foncteur... ocaml). Cependant, Scala prend en charge un "objet" singleton qui permet l'héritage polymorphe fonctionnel paramétrique.

2voto

Marcelo Points 6708

Cela n'est pas possible car le A ne contiendra pas nécessairement un add() méthode. Le compilateur ne l'autorisera pas, car il ne peut pas garantir que cela fonctionnera.

1voto

Paul Boddington Points 9671

En fait, vous peut invoquer une méthode statique sur un paramètre de type (bien que cela ne soit pas fait dynamiquement).

Essayez ceci :

public class Main<T extends Collections> {

    public static void main(String[] args) {
        new Main<>().foo();
    }

    void foo() {
        List<Integer> list = Arrays.asList(2, 3, 1);
        T.sort(list);
        System.out.println(list);
    }
}

Je ne sais pas pourquoi les concepteurs du langage ont décidé que c'était une bonne idée de permettre cela.

1voto

Ferran Maylinch Points 394

Il est pratique d'obtenir une valeur d'une énumération que l'on ne connaît pas à l'avance.

public static <T extends Enum<T>> T enumFromName(String name, Class<T> clazz) {
    return StringUtils.isEmpty(value) ? null : T.valueOf(clazz, name);
}

Avoir :

enum ProductType { FOOD, ELECTRONICS, ... }

Vous pouvez le faire :

ProductType p = enumFromName("FOOD", ProductType.class);

Je suppose que vous pouvez également en tirer parti dans vos propres classes, bien que je ne recommande pas l'utilisation de static trop.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X