2009-06-01 2 views
5

Я хотел бы создать метод инициализации для класса Java, который принимает 3 параметра:Метод Java с параметрами размера принудительного массива?

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; 
} 

Вы можете заметить, что этот код является неправильным. Переменная SIZE не определена. Моя проблема в том, что я хотел бы передать в 3 массива, но я хотел бы знать, могу ли я гарантировать, что три массива ВСЕ имеют одинаковый размер массива. Таким образом цикл for не будет терпеть неудачу, поскольку конструктор в цикле for использует все параметры массивов.

Возможно, у Java есть другая функция, которая может обеспечить решение моей проблемы. Я мог бы принять еще один параметр SIZE, который будет использоваться в цикле for, но это не решает мою проблему, если параметры 1 и 2 имеют размер 10, а третий параметр - массив размера 9.

Так просто перефразировать я не был ясен. Как я могу гарантировать, что все три аргумента - все массивы, содержащие одинаковое количество элементов?

Использование дополнительного параметра, который задает размеры массива, не очень изящный и грязный. Он также не решает проблему, параметры массива содержат массивы различного размера.

ответ

16

Вы не можете принудительно выполнить это во время компиляции. Вы в основном должны проверить его во время выполнения, и выбросить исключение, если ограничение не выполняется:

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

Благодаря Джон, отличный ответ! –

+2

Это хороший пример того, что я считаю неправильным способом использования NullPointerException. Я сделал бы индивидуальную проверку для каждого из переданных параметров if (employeeNames == null) { throw new IllegalArgumentException ("employeeNames == null"); } Это делает stacktrace гораздо более полезной для диагностики проблемы. –

+0

Я думаю, что в этом случае было бы приемлемым бросить NPE (хотя никто не согласился бы с броском IAE); но, возможно, в качестве компромисса в этой дискуссии/споре, было бы лучше включить сообщение с NPE. –

2

Поскольку массивы передается в не не генерируются до времени выполнения, это не представляется возможным предотвратить метод вызов от завершения в зависимости от характеристик передаваемого массива в качестве проверки времени компиляции.

Как упоминал Джон Скит, единственный способ указать проблему - бросить IllegalArgumentException или тому подобное во время выполнения, чтобы остановить обработку, когда метод вызывается с неправильными параметрами.

В любом случае в документации должны быть четко указаны ожидания и «контракт» для использования метода - переход из трех массивов, имеющих одинаковые длины. Вероятно, было бы неплохо отметить это в Javadocs для метода.

0

Путь к юбке вокруг проблемы заключается в создании строитель, например, 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

Я не думаю, что строитель здесь подходит, потому что в API нет ничего, что могло бы предполагать, что нужны возрасты, имена и зарплаты. Builder подходит, когда вы можете иметь необязательные аргументы. Это также довольно сложно по сравнению с ответом Джона Скита. –

+0

@ Ken Liu: Both решает одну и ту же проблему - я опубликовал это, потому что другое решение уже опубликовано так, чтобы дублировать ?, и это альтернатива, которая требует некоторого рассмотрения. Действительно, в API нет ничего, что могло бы предполагать, что это требуемые аргументы, но это ничего не берет от шаблон строителя. – Chii

Смежные вопросы