2009-06-01 9 views
5

Je voudrais créer une méthode d'initialisation d'une classe Java qui accepte 3 paramètres:Méthode Java avec paramètres de taille de tableau appliqués?

Employee[] method(String[] employeeNames, Integer[] employeeAges, float[] employeeSalaries) 
{ 
    Employee myEmployees[] = new Employee[SIZE];// dont know what size is 

    for (int count = 0; count < SIZE; count++) 
    { 
     myEmployees[count] = new Employee(employeeNames[count], employeeAges[count], employeeSalaries[count]); 
    } 
    return myEmployees; 
} 

Vous remarquerez peut-être que ce code est erroné. La variable TAILLE n'est pas définie. Mon problème est que je voudrais passer dans 3 tableaux, mais je voudrais savoir si je peux m'assurer que les trois tableaux sont tous de la même taille de tableau. De cette façon, la boucle for n'échouera pas, car le constructeur de la boucle for utilise tous les paramètres des tableaux.

Peut-être Java a une fonctionnalité différente qui peut appliquer une solution à mon problème. Je pourrais accepter un autre paramètre appelé SIZE qui sera utilisé dans la boucle for, mais cela ne résout pas mon problème si les paramètres 1 et 2 sont de taille 10 et le 3ème paramètre est un tableau de taille 9.

Je ne sais pas si je n'étais pas clair. Comment puis-je faire en sorte que les 3 arguments soient tous des tableaux contenant exactement le même nombre d'éléments?

L'utilisation d'un paramètre supplémentaire qui spécifie les tailles de matrice n'est pas très élégante et plutôt sale. Cela ne résout pas non plus le problème que les paramètres du tableau contiennent des tableaux de tailles différentes.

Répondre

16

Vous ne pouvez pas appliquer cela à la compilation. Vous avez essentiellement à vérifier au moment de l'exécution, et lancer une exception si la contrainte est pas remplie:

Employee[] method(String[] employeeNames, 
        Integer[] employeeAges, 
        float[] employeeSalaries) 
{ 
    if (employeeNames == null 
     || employeeAges == null 
     || employeeSalaries == null) 
    { 
     throw new NullPointerException(); 
    } 
    int size = employeeNames.length; 
    if (employeesAges.length != size || employeeSalaries.length != size) 
    { 
     throw new IllegalArgumentException 
      ("Names/ages/salaries must be the same size"); 
    } 
    ... 
} 
+0

Merci Jon, excellente réponse! –

+2

Ceci est un bon exemple de ce que je considère comme la mauvaise façon d'utiliser NullPointerException. Je ferais une vérification individuelle pour chacun des paramètres passés if (employeeNames == null) { throw nouveau IllegalArgumentException ("employeeNames == null"); } Cela rend la stacktrace beaucoup plus utile pour diagnostiquer le problème. –

+0

Je pense qu'il est tout aussi acceptable de lancer un NPE dans ce cas (alors que personne ne serait pas d'accord pour lancer un IAE); mais peut-être comme un peu de compromis dans ce débat/controverse, il serait préférable d'inclure un message avec le NPE. –

2

Puisque les réseaux étant passés dans ne sont pas générés avant l'exécution, il est impossible d'empêcher la méthode appel à partir de l'achèvement en fonction des caractéristiques du tableau transmis en tant que vérification à la compilation. Comme Jon Skeet l'a mentionné, la seule façon d'indiquer un problème est de lancer un IllegalArgumentException ou similaire à l'exécution pour arrêter le traitement lorsque la méthode est appelée avec les mauvais paramètres.

Dans tous les cas, la documentation doit clairement noter les attentes et le «contrat» pour l'utilisation de la méthode - passage de trois tableaux qui ont les mêmes longueurs. Ce serait probablement une bonne idée de le noter dans les Javadocs pour la méthode.

0

Une façon de contourner le problème est de créer un constructeur, par exemple, EmployeeArrayBuilder,

public class EmployeeArrayBuilder { 
    private Integer arraySize = null; 
    private String[] employeeNames; 
    public EmployeeArrayBuilder addName(String[] employeeNames) { 
     if (arraySize == null) { 
     arraySize = employeeNames.length; 
     } else if (arraySize != employeeNames.length) { 
     throw new IllegalArgumentException("employeeNames needs to be " + arraySize + " in length"); 
     } 
     this.employeeNames = employeeNames; 
     return this; 
    } 
    public EmployeeArrayBuilder addSalaries(float[] employeeSalaries) {/* similar to above */} 
    public EmployeeArrayBuilder addAges(Integer[] employeeAges) {/* similar */} 
    public Employee[] build() { 
     // here, you can do what you needed to do in the constructor in question, and be sure that the members are correctly sized. 
     Employee myEmployees[] = new Employee[arraySize ];// dont know what size is    
     for (int count = 0; count < arraySize ; count++) { 
      myEmployees[count] = new Employee(employeeNames[count], employeeAges[count], employeeSalaries[count]); 
     } 
     return myEmployees; 
    } 
} 
+0

Je ne pense pas qu'un constructeur est approprié ici parce qu'il n'y a rien dans l'API pour suggérer que les âges, les noms et les salaires sont tous requis.Builder est approprié quand vous pouvez avoir des arguments optionnels.Elle est aussi plutôt complexe par rapport à la réponse de Jon Skeet –

+0

@Ken Liu: Les deux résout le même problème - j'ai posté ceci parce que l'autre solution est déjà postée alors pourquoi dupliquer? et ceci est une alternative qui mérite une certaine considération.En effet il n'y a rien dans l'API pour suggérer que ce sont des arguments obligatoires, mais cela n'enlève rien le modèle de constructeur. – Chii

Questions connexes