2016-06-22 8 views
1

Je lis livre pour OCP de Auteur Jeanne Boyarsky et Scott Selikoff, livre en disant: Page # 122? super-cordes Limite inférieure Java

? super String 

avec une limite inférieure, nous disons Java que la liste sera une liste d'objets String ou une liste de certains objets qui sont superclasse de Chaîne

List<? super String> superString = new ArrayList<>(); 
    superString.add(new String());// Valid 
    superString.add(new Object()); // Not Valid ? Why?. Object is a super class of String 

Autre exemple:

List<? super IOException> exceptions = new ArrayList<Exception>(); 
exceptions.add(new Exception()); // Invalid, why ? Exception is a superclass of IOException 
exceptions.add(new IOException()); 
exceptions.add(new FileNotFoundException()); 

Je pense que cette déclaration

avec une limite inférieure, nous disons Java que la liste sera une liste d'objets String ou une liste de certains objets qui sont superclasse de Chaîne

Devrait être

avec une limite inférieure, nous disons Java que la liste est une liste d'objets String ou une liste de certains objets whoes super classe est une chaîne

si ce cas est vrai, alors pourquoi nous utilisons

List<? super IOException> exceptions = new ArrayList<Exception>(); 

au lieu de

List<? super IOException> exceptions = new ArrayList<IOException>(); 
+0

connexes: http: // stackoverflow.com/questions/3847162/java-generics-super-keyword – Maroun

Répondre

2

Vous devez comprendre que ces limites (inférieur et supérieur) existent pour restreindre/spécifier le type de la variable, et non pour restreindre/spécifier le type d'éléments à l'intérieur d'une telle collection.

Un exemple:

List<? super String> variable = new ArrayList<CharSequence>(); 

Avec cette déclaration, vous devez d'abord créer un ArrayList dont les éléments peuvent être de type CharSequence ou un sous-type de celui-ci (par exemple String ou StringBuilder).

Avec cette déclaration, il devrait être clair que vous ne pouvez pas ajouter un Object dans cette liste. Il n'implémente tout simplement pas l'interface CharSequence. Le compilateur prend soin de cela.

Des limites inférieures et supérieures existent pour la création de sous-types de types génériques. Leur utilisation est expliquée au this question about PECS.

En fait, une List<? super String> est une liste avec un type d'élément en béton, mais ce type de béton n'est pas connu pour le moment. Voir mon exemple d'initialisation. Le type concret est le CharSequence.Cela signifie simplement que tous les éléments sont de ce type concret (ou un sous-type), mais cela n'est pas connu dans le propre type de la variable.

+0

En d'autres termes: à la variable on peut assigner une liste de certains type super (String, CharSequence, Object), et le compilateur peut seulement savoir que les chaînes peuvent être mettre en toute sécurité dans la liste. –

+0

'Liste exceptions = new ArrayList (); exceptions.add (nouvelle exception()); // Invalide, pourquoi? Exception est une superclasse d'exceptions IOException .add (nouvelle IOException()); // si nous avons vraiment besoin de créer une liste pourquoi cela est valide exceptions.add (new FileNotFoundException()); // et celui-ci est également valide 'pouvez-vous s'il vous plait donner un exemple complet. Je suis toujours confus. –

+0

@ShahidGhafoor Il est invalide, car vous auriez pu initialiser la variable comme ça: 'List exceptions = new ArrayList () '. Vous n'êtes pas autorisé à ajouter une 'Exception' dans une telle liste. Le compilateur doit interdire cela. – Seelenvirtuose

0

est ici un lien vers une bonne explication Difference between <? super T> and <? extends T> in Java

Le livre est correct « ? Super-chaîne » signifie que la liste peut contenir des chaînes ou une super-type de chaîne (par exemple. Object, CharSequence)

En vous exemple:

List<? super String> superString = new ArrayList<>(); 
    superString.add(new String());// 1 
    superString.add(new Object()); // 2 

opérations d'écriture:

1 - est valable pour tout type de liste que vous auriez pu créer, depuis Stri ng est un objet, un CharSequence ...

List<? super String> list = new ArrayList<Object>(); 
list.add("String"); 

2 - pas valide car elle ne couvre pas tous les cas

List<? super String> list = new ArrayList<String>(); 
list.add(new Object()); 

Compte tenu du type déclaré List<? super String> vous ne pouvez ajouter des chaînes (et sous-types de chaîne), rien de moins qu'une chaîne (supertypes) peut ne pas correspondre au type d'élément réel.

Exemple:

Voici un exemple:

interface MyInterface { 

} 

class MyInterfaceImpl implements MyInterface { 

} 

class MyInterfaceImplExtra extends MyInterfaceImpl { 

} 

Vous avez sans doute les situations suivantes:

List<? super MyInterfaceImpl> myList = new ArrayList<MyInterfaceImpl>(); 

ne compile pas parce que la variable myList peut pointer vers une liste de deux MyInterfaceImpl ou MyInterface ou Object. Lorsque vous ajoutez à la liste, vous ne savez pas exactement quel type de liste vous avez réellement, donc vous n'êtes autorisé que les valeurs qui sont applicables à tous les cas.

myList.add(new MyInterface(){}); // - compile error "not applicable for the arguments" 
myList.add(new MyInterfaceImpl()); // - works fine 
myList.add(new MyInterfaceImplExtra()); // - works fine 

Un exemple où vous obtenez une liste de valeurs. Le type d'élément est Object, un type plus concret ne peut pas être garanti. Par exemple ici, vous attendez cordes mais obtenez un List<? super String> qui contient en fait des objets si vous obtenez un java.lang.ClassCastException

List<String> result = (List<String>) getList(); 
System.out.println(result.get(0)); 

public static List<? super String> getList(){ 
    List<Object> list = new ArrayList<Object>(); 
    list.add(new Object()); 
    return list; 
} 

Exemple d'utilisation en Java 8:

Vous avez la déclaration de méthode suivante dans l'interface de flux qui limite le prédicat type à être T ou supertype.

Stream<T> filter(Predicate<? super T> predicate); 

Cela garantit que donné une personne de classe qui définit le nom et les employés qui s'étend personne et définit un identifiant de champ supplémentaire, vous ne pouvez pas faire quelque chose comme ceci:

List<Person> list = new ArrayList<Person>() {{ 
     add(new Person("John")); 
     add(new Person("Max")); 
     add(new Person("Megan")); 
    }}; 

list.stream().filter((Employee e) -> e.getId().startsWith("1")); // compile error 
+0

'? super chaîne "signifie que la liste peut contenir des Strings ou un supertype de String (par exemple, Object, CharSequence)' pouvez-vous donner un exemple complet où '? super String' prend à la fois String et supertype Object .bcz réponse toujours pas claire pour moi. . Merci –