2011-03-25 25 views
7

Varargs kullanan bir Java işlevinin (veya yapıcınızın) varargs ile mi yoksa bir diziyle mi çağrıldığını öğrenmenin bir yolu var mı? Java: Fonksiyonun varargs veya array ile çağrılıp adlandırılmadığını öğrenin

Aşağıdaki olduğunu varsayalım:

public class MyCompositeObjects { 

    MyObject[] objects; 

    MyCompositeObjects(MyObjects... objects) { 
     this.objects = Arrays.copyOf(objects,objects.length); 
     // or just: this.objects = objects; ? 
    } 

    // ... 
} 

yapıcı sonradan değişebilir tek MyObject[] argüman ile çağrılabilir ve Kurucuda dizi kopyalamak yoksa bu değişiklikleri uygulanacaktır üye değişkeni objects da değil mi? Ancak, kurucu birkaç MyObject s ile çağrılırsa, daha sonra sınıfın dışında değiştirmek için * dizisine başka bir gönderme yapılmaz, dolayısıyla doğrudan onu atayabilirim. Kurucunun içinde (veya genellikle, varargs alan herhangi bir işlev) nasıl çağrıldığını söyleyebilir miyim?

* nb: Bunun için belirli bir adı var mı? Sadece anonim bir dizi mi?

cevap

9

Hayır, yapamazsınız. Tamamen şeffaf olması gerekiyordu - bu kodu:

new MyCompositeObjects(a, b); 

new MyCompositeObjects(new MyObjects[] { a, b }); 

Eğer güven sizi arayanlar doğru olanı yapmak olabilir, her zaman iki statik yöntemler oluşturabilir ve tam olarak eşdeğerdir

public static MyCompositeObjects createWithCopy(MyObjects[] values) { 
    return new MyCompositeObjects(Arrays.copyOf(values, values.length)); 
} 

public static MyCompositeObjects createWithoutCopy(MyObjects... values) { 
    return new MyCompositeObjects(values); 
} 

private MyCompositeObjects(MyObjects[] values) { 
    this.objects = values; 
} 

Not "kopya ile" sürüm kullanmalarını çıkartmaya yarayacak varargs kullanmaz nasıl: yapıcı özel yapabilir doğru versiyon

4

Bilmenin tek yolu kodu ayrıştırmaktır. Bunun nedeni, varargs'ın temel bir derleme zamanı özelliğidir ve programın çalışma şeklini değiştirmez.

Şüphe durumunda diziyi her zaman kopyalarım. Bu bilmiyorsanız, bu bir performans sorunu olacak.

BTW: Aşağıdakileri yapabilirsiniz.

MyCompositeObjects(MyObjects o1, MyObjects... objects) { 

MyCompositeObjects(MyObjects[] objects) { 

Bununla birlikte, bu sizin istediğiniz şeyin tersini yapacaktır.

Başka bir seçenek statik bir fabrika kullanmaktır.

private MyCompositeObjects(MyObjects[] objects) { 
    this.objects = objects; 
} 

MyCompositeObjects create(MyObjects... objects) { 
    return new MyCompositeObjects(objects.close()); 
} 

MyCompositeObjects createNotCopied(MyObjects... objects) { 
    return new MyCompositeObjects(objects, false); 
} 

Daha az güvenli sürüm için daha hantal yöntem adını kullanın. Bu, bir yöntemin fazla düşünülmeden seçilmesi durumunda, güvenli sürümün kullanılmasının daha olası olduğu anlamına gelir.

+0

Statik fabrika örneğinizde sorunlar var. "Copy" boolean bir constructor argümanı ve objects.close() öğesine yapılan çağrı değildir. –