2009-06-01 13 views
5

Ben 3 parametre kabul eden bir Java sınıfı için bir başlatma yöntemi oluşturmak istiyorum:Zorunlu Dizi Boyut Parametreli Java Yöntemi?

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

Bu kodu yanlış olduğunu fark edebilirsiniz. BOYUTU değişkeni tanımlanmamış. Benim sorunum, 3 dizide geçmek istediğimdir, ancak üç dizinin aynı dizi boyutunun TÜMÜ olduğunu garanti edip edemeyeceğimi bilmek isterim. For döngüsü içindeki kurucu dizilerin tüm parametrelerini kullandığı için for döngüsü başarısız olmaz.

Belki de Java'nın benim sorunum için bir çözüm uygulayabilen farklı bir özelliği vardır. For döngüsünde kullanılacak olan SIZE adında başka bir parametreyi kabul edebilirim, ancak bu parametreler 1 ve 2'nin boyutu 10 ise ve 3. parametre boyut 9'un bir dizilimi ise, bu sorunu çözmez.

Sadece açıklığa kavuşturmak berrak değildi. 3 argümanın hepsinin aynı sayıda elemanı içeren diziler olduğunu nasıl uygulayabilirim?

Dizi boyutlarını belirten ek bir parametre kullanmak çok zarif ve kirli değildir. Ayrıca, dizi parametrelerinin farklı boyutlu diziler içermesi sorunu da çözmez.

cevap

16

Bunu derleme zamanında zorlayamazsınız. kısıt yerine getirilmediği takdirde Temelde yürütme anda kontrol etmek ve bir istisna vardır:

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

Teşekkür Jon, mükemmel cevap! –

+2

THis, NullPointerException'ı kullanmanın yanlış yolunu düşündüğümün iyi bir örneğidir. geçirilen parametrelerin her biri için bir kişisel kontrol yaparsam (employeeNames == null) { yeni IllegalArgumentException ("employeeNames == null") atarsa; } Bu, stacktrace'ı sorunu tanılamak için çok daha yararlı hale getirir. –

+0

Sanırım bu durumda bir NPE atmak kadar kabul edilebilir (hiç kimse bir IAE atmaya katılmazken); ama belki de bu tartışma/tartışmadaki bir uzlaşma olarak, NPE'ye bir mesaj eklemek daha iyi olacaktır. –

2

diziler çalışma zamanı kadar oluşturulmaz içinde geçirilen yana, yöntemini önlemek mümkün değildir Bir derleme zamanı denetimi olarak geçirilen dizinin özelliklerine bağlı olarak tamamlama çağrısı. Jon Skeet'in belirttiği gibi, bir sorunu belirtmenin tek yolu, yönteme yanlış parametrelerle çağrıldığında işlemeyi durdurmak için çalışma zamanında IllegalArgumentException veya benzeri atmaktır. Her durumda, belgelerin, aynı uzunluklara sahip üç diziden geçerek, yöntemi kullanmak için beklentileri ve "sözleşmeyi" açıkça belirtmesi gerekir. Bu yöntem için Javadocs'ta bunu not etmek iyi bir fikir olabilir.

0

soruna etek bir yolu, örneğin bir inşaatçı, EmployeeArrayBuilder oluşturmak için

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

Burada uygun olan, çağlar, isimler ve maaşların gerekli olduğunu önermek için API'da hiçbir şey yoktur.Yalnızca isteğe bağlı argümanlara sahip olduğunuzda, uygun olan bu, Jon Skeet'in cevabına kıyasla oldukça karmaşıktır. –

+0

@Ken Liu: Her ikisi de aynı sorunu çözer - bunu diğer çözüm gönderildiği için gönderdim çünkü neden yinelenen? ve bu, bazı değerlendirmeleri garanti eden bir alternatiftir.Gerçekte gerekli argümanlar olduğunu göstermek için API'de hiçbir şey yoktur, ama bu hiçbir şey almaz. Oluşturucu desen – Chii