299 votes

Comment utiliser la classe<T> en Java ?</T>

Il y a une bonne discussion de Génériques et de ce qu'ils font réellement derrière les scènes plus à cette question, de sorte que nous savons tous que l' Vector<int[]> est un vecteur d'entier tableaux, et HashTable<String, Person> est un tableau dont les clés sont des chaînes de caractères et les valeurs Persons. Cependant, ce que les souches moi est l'utilisation de l' Class<>.

La classe java Class est censé également prendre un nom de modèle, (ou alors j'ai été informé par le jaune souligner dans eclipse). Je ne comprends pas ce que je dois mettre dedans. Le point de l'ensemble de l' Class objet, c'est quand vous n'avez pas pleinement les informations sur un objet, à la réflexion et à de telles. Pourquoi a-t-il me préciser la classe à laquelle l' Class objet? De toute évidence, je ne sais pas, ou je ne serais pas à l'aide de l' Class objet, je voudrais utiliser le spécifique.

239voto

Kanagavelu Sugumar Points 1206

Tout ce que nous savons est "Toutes les instances d'une quelconque classe d'actions de la même java.lang.Class l'objet de ce type de classe"

e.g)

Student a = new Student();
Student b = new Student();

Ensuite, a.getClass() == b.getClass() est vrai.

Supposons maintenant

Teacher t = new Teacher();

sans les génériques ci-dessous est possible.

Class studentClassRef = t.getClass();

Mais c'est mal connaître ..?

e.g) public void printStudentClassInfo(Class studentClassRef) {} peut être appelée avec Teacher.class

Ceci peut être évité par l'utilisation de médicaments génériques.

Class<Student> studentClassRef = t.getClass(); //Compilation error.

Maintenant, qu'est-ce que T ?? T est le type des paramètres (aussi appelés variables de type); délimités par des crochets (<>), suit le nom de la classe.

e.g) class name<T1, T2, ..., Tn>

Donc, Class<T> représente un objet de classe de classe spécifique de type 'T'.

Supposons que vos méthodes de la classe a à travailler avec type inconnu paramètres comme ci-dessous

/**
 * Generic version of the Car class.
 * @param <T> the type of the value
 */
public class Car<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

Ici T peut être utilisé en tant que String type de CarName

OU T peut être utilisé en tant que Integer type de modelNumber,

OU T peut être utilisé en tant que Object type valide voiture instance.

Maintenant, voici ce qui précède est la simple POJO qui peuvent être utilisés de la même manière lors de l'exécution.

Méthodes Génériques

Méthodes génériques sont des méthodes qui introduisent leurs propres paramètres de type. Ceci est similaire à la déclaration d'un type générique, mais le type du paramètre de la portée est limitée à la méthode où il est déclaré. Statiques et non statiques et méthodes génériques sont autorisés, ainsi que les génériques de constructeurs de classe.

La syntaxe d'une méthode générique comprend un paramètre de type, à l'intérieur des crochets, et apparaît avant le retour de la méthode type. Pour les méthodes génériques, le paramètre du type d'article doit apparaître avant le retour de la méthode type.

 class Util {
    // Generic static method
    public static <K, V, Z, Y> boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

 class Pair<K, V> {

    private K key;
    private V value;
}

Ici, <K, V, Z, Y> est la déclaration des types utilisés dans les arguments de la méthode qui devrait, avant que le type de retour qui est - boolean ici.

Dans le ci-dessous; la déclaration de type <T> n'est pas requis au niveau de la méthode, car il est déjà déclaré au niveau de la classe.

class MyClass<T> {
   private  T myMethod(T a){
       return  a;
   }
}

Mais ci-dessous est faux, où K, V, Z, Y sont des variables de type de classe différente Pair

class Util <K, V, Z, Y>{
    // Generic static method
    public static  boolean compare(Pair<K, V> p1, Pair<Z, Y> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}

D'AUTRES SCÉNARIOS SONT

class MyClass<T> {

        //Type declaration <T> already done at class level
        private  T myMethod(T a){
            return  a;
        }

        //<T> is overriding the T declared at Class level;
        //So There is no ClassCastException though a is not the type of T declared at MyClass<T>. 
        private <T> T myMethod1(Object a){
                return (T) a;
        }

        //Runtime ClassCastException will be thrown if a is not the type T (MyClass<T>).  
        private T myMethod1(Object a){
                return (T) a;
        }       

        // No ClassCastException        
        // MyClass<String> obj= new MyClass<String>();
        // obj.myMethod2(Integer.valueOf("1"));
        // Since type T is redefined at this method level.
        private <T> T myMethod2(T a){
            return  a;
        }

        // No ClassCastException for the below
        // MyClass<String> o= new MyClass<String>();
        // o.myMethod3(Integer.valueOf("1").getClass())
        // Since <T> is undefined within this method; 
        // And MyClass<T> don't have impact here
        private <T> T myMethod3(Class a){
            return (T) a;
        }

        // ClassCastException for o.myMethod3(Integer.valueOf("1").getClass())
        // Should be o.myMethod3(String.valueOf("1").getClass())
    private  T myMethod3(Class a){
        return (T) a;
    }


        // Class<T> a :: a is Class object of type T
        //<T> is overriding of class level type declaration; 
        private <T> Class<T> myMethod4(Class<T> a){
            return  a;
        }
    }

Et enfin la méthode Statique doit toujours explicite <T> déclaration; Il l'habitude de dériver de la classe de niveau Class<T>. C'est en raison du niveau de la Classe T est lié avec instance.

159voto

Yuval Points 3350

Utilisez la version génériques de classe vous permet, entre autres choses, d’écrire des choses comme

et puis, vous pouvez être sûr que l’objet de classe vous recevez s’étend `` , et une instance instantanée de cette classe sera (au moins) une Collection.

40voto

raupach Points 1443

À partir de la Documentation de Java:

[...] Plus surprenant, la classe la Classe a été generified. Classe littéraux maintenant fonctionner comme des jetons de type, fournissant à la fois au moment de l'exécution et le type de compilation de l'information. Cela permet à un style de la statique des usines illustré par le getAnnotation méthode dans le nouveau AnnotatedElement interface:

<T extends Annotation> T getAnnotation(Class<T> annotationType); 

C'est une méthode générique. Il en déduit la valeur de son paramètre de type T de son argument, et retourne une instance appropriée de T, comme illustré par l'extrait suivant:

Author a = Othello.class.getAnnotation(Author.class);

Avant les génériques, vous auriez dû cast le résultat d'Auteur. Aussi, vous aurait eu aucun moyen de faire le compilateur de vérifier que le paramètre représenté une sous-classe de l'Annotation. [...]

Eh bien, je n'ai jamais eu à utiliser ce genre de trucs. N'importe qui?

11voto

Kire Haglin Points 2402

J’ai trouvé `` utile quand je crée les recherches de registre de service. Par exemple

8voto

Ryan Anderson Points 390

Oracle a un tutoriel sur les génériques qui parle de types raw avec des exemples : http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html

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