具有强制数组大小参数的Java方法?

时间:2009-06-01 08:41:38

标签: java class architecture

我想为接受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且第3个参数是大小为9的数组,则不能解决我的问题。

所以只是为了重新说道,我不清楚。如何强制3个参数都是包含完全相同数量元素的数组?

使用指定数组大小的额外参数不是很优雅而且很脏。它也没有解决数组参数包含不同大小的数组的问题。

3 个答案:

答案 0 :(得分:17)

您无法在编译时强制执行此操作。您基本上必须在执行时检查它,并在不满足约束时抛出异常:

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");
    }
    ...
}

答案 1 :(得分:2)

由于传入的数组直到运行时才生成,因此无法阻止方法调用完成,具体取决于作为编译时检查传入的数组的特性。

正如Jon Skeet所提到的,指出问题的唯一方法是在运行时抛出IllegalArgumentException之类的东西,以便在使用错误的参数调用方法时停止处理。

在任何情况下,文档都应该清楚地说明使用该方法的期望和“合同” - 传入三个具有相同长度的数组。在方法的Javadocs中注意这一点可能是个好主意。

答案 2 :(得分:1)

解决问题的方法是创建一个构建器,例如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;
   }
}