2009-02-18 8 views
1

J'ai écrit ce code de test simple, en adaptant un morceau d'un livre, pour m'aider à comprendre le fonctionnement des méthodes génériques en Java. La ligne que j'ai marquée est supposé pour fonctionner, pourquoi n'est-ce pas?Generic Method Fail

import java.util.*; 

class Test { 
public static void main(String args[]){ 
    List<Number> input = null; 
    List<Number> output=null; 

    output = Test.process(input); // fail, why?? 

    } 
public static <E extends Number> List <? super E> process (List <E> nums){ 

    List <E>eList = new ArrayList<E>(); 
    return eList; 
    } 

} 

modifier: Eh bien, le code fonctionne lors du changement List<? super E>-List<E>, c'est super, mais je ne suis toujours pas sûr si je peux avoir manqué quelque chose ou si le livre que je pris ce billet depuis peut-être une erreur. S'il vous plaît lire la question car il semble y avoir:

  1. une méthode déclarée Étant donné que:

public static < E étend Numéro> Liste <? Super E> Processus (Liste nums)

Un programmeur veut utiliser cette méthode comme ceci:

// INSERT DECLARATIONS HERE 
    output = process(input); 

Quelles paires de déclarations peuvent être placées à // INSERT ICI DECLARATIONS pour permettre le code compiler? (Choisissez toutes les réponses qui s'appliquent.)

A. ArrayList<Integer> input = null; 
    ArrayList<Integer> output = null; 

B. ArrayList<Integer> input = null; 
    List<Integer> output = null; 

C. ArrayList<Integer> input = null; 
    List<Number> output = null; 

D. List<Number> input = null; 
    ArrayList<Integer> output = null; 

E. List<Number> input = null; 
    List<Number> output = null; 

F. List<Integer> input = null; 
    List<Integer> output = null; 

G. None of the above. 

Réponse: B, E et F sont corrects. Le type de retour du processus est définitivement déclaré comme List, et non comme ArrayList, donc A et D sont erronés. C est faux parce que le type de retour est évalué à List<Integer>, et que ne peut pas être affecté à une variable de type List<Number>. Bien sûr, tout ceci provoquerait probablement un NullPointerException puisque les variables sont toujours nulles - mais la question nous a seulement demandé pour obtenir le code à compiler.

Aucune des options mentionnées sur le livre n'a fonctionné sur mon code. Puis-je le marquer comme une erreur de la part de Kathy Sierra ou est-ce qu'il me manque quelque chose ici?

Répondre

7

Le problème est que vous déclarez le type de retour de votre méthode comme

List<? super E>, i.e. List<? super Number> 

mais assigner à une

List<Number> 

donc vous devez soit l'affecter à un

List<? super Number> 

ou déclarer le type de retour comme

List<E> i.e. List<Number> 

(mise en forme verbeux parce que le code en ligne ne montre pas génériques correctement.)

Si les revendications de livres assignant la valeur de retour de la méthode est possible de la manière vous le décrivez alors, en effet, il semble que ce soit une erreur dans le livre. Ce serait correct si la méthode renvoyait une liste de E (comme ci-dessus).

+0

hmmm .. Je vais éditer la question. Je pense qu'il peut y avoir une erreur sur le livre .. – andandandand

1

essayer:

import java.util.*; 

class Test { 
public static void main(String args[]){ 
    List<Number> input = null; 
    List<Number> output=null; 

    output = Test.process(input); // fail, why?? 

    } 
public static <E extends Number> List <E> process (List <E> nums){ 

    List <E>eList = new ArrayList<E>(); 
    return eList; 
    } 

} 
+0

Peut-être une brève explication pour aller avec votre échantillon de code? :) –

+0

Oh .. pourquoi avez-vous enlevé la liste ? – andandandand

0

Votre méthode renvoie List. Nous ne savons pas ce que c'est une liste de, mais c'est certainement une liste de certains superclasse de Number. Par exemple: peut-être qu'il renvoie une liste de Object - l'appelant ne sait pas. Cependant, nous savons que quel que soit le type de List il revient, il est toujours bon d'y mettre un Number. Vous l'attribuez à un List of Number. Cela signifie que chaque fois que vous appelez output.get(n), vous aurez toujours un Number de retour.

Voir le problème? La valeur de retour de process() n'honore pas le contrat que doit respecter output.

Questions connexes