Korkarım varargs. Onları ne için kullanacağımı bilmiyorum.
Ayrıca, insanların istedikleri kadar argüman geçirmelerine izin vermek tehlikeli hissettiriyor.
Bunları kullanmak için iyi bir yer olabilecek bir bağlam örneği nedir?
Korkarım varargs. Onları ne için kullanacağımı bilmiyorum.
Ayrıca, insanların istedikleri kadar argüman geçirmelerine izin vermek tehlikeli hissettiriyor.
Bunları kullanmak için iyi bir yer olabilecek bir bağlam örneği nedir?
Yanıtlar:
Varargs , belirsiz sayıda nesne ile ilgilenmesi gereken herhangi bir yöntem için kullanışlıdır . Bunun iyi bir örneği . Biçim dizesi herhangi bir sayıda parametreyi kabul edebilir, bu nedenle istediğiniz sayıda nesneyi iletmek için bir mekanizmaya ihtiyacınız vardır.String.format
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
İyi bir kural şöyle olacaktır:
Msgstr "Girdi olarak T dizisine ihtiyaç duyan herhangi bir yöntem (veya yapıcı) için varargs kullanın".
Bu, bu yöntemlere çağrı yapmayı kolaylaştıracaktır (yapmaya gerek yoktur new T[]{...}
).
List<T>
Bu bağımsız değişkeni yalnızca girdi için olması koşuluyla, bağımsız değişkeni içeren yöntemleri içerecek şekilde genişletebilirsiniz (yani, liste yöntem tarafından değiştirilmemiştir).
Ayrıca, f(Object... args)
belirsiz API'lerle bir programlama yoluna kaydığı için kullanmaktan kaçınırım .
Örnekler açısından, ben bir çağrıda birkaç s ekleyebilirsiniz DesignGridLayout , kullandım JComponent
:
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
Yukarıdaki kodda add () yöntemi olarak tanımlanır add(JComponent... components)
.
Son olarak, bu tür yöntemlerin uygulanması, boş bir vararg ile çağrılabileceği gerçeğine dikkat etmelidir! En az bir argüman uygulamak istiyorsanız, o zaman çirkin bir numara kullanmalısınız:
void f(T arg1, T... args) {...}
Bu hileyi çirkin görüyorum çünkü yöntemin uygulanması sadece T... args
argümanlar listesinde olmaktan daha az basit olacaktır .
Bu varargs ile ilgili noktayı açıklığa kavuşturmayı umuyor.
if (args.length == 0) throw new RuntimeException("foo");
Bunun yerine bir ön koşul kontrolü eklemeyi düşündünüz mü ? (Arayan kişi sözleşmeyi ihlal ettiği için)
void f(T arg1, T... args)
, çalışma zamanına kadar beklemeye gerek kalmadan, hiçbir zaman argüman olmadan çağrılmamasını sağlar.
Hata ayıklama amacıyla günlüklere çıkış için varargs kullanıyorum.
Uygulamamdaki hemen hemen her sınıfın bir debugPrint () yöntemi var:
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
Sonra, sınıfın yöntemleri içinde, aşağıdaki gibi çağrıları var:
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
Kodumun çalıştığından memnun olduğumda, günlüklerin çok fazla gereksiz ve istenmeyen bilgi içermemesi için debugPrint () yöntemindeki kodu yorumluyorum, ancak debugPrint () 'e tek tek çağrıları uncommented bırakabilirsiniz. Daha sonra, bir hata bulursam, ben sadece debugPrint () kodunu uncomment ve debugPrint () tüm çağrıları yeniden etkinleştirilir.
Tabii ki, varargs kadar kolay eschew olabilir ve bunun yerine aşağıdakileri yapabilirim:
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
Ancak, bu durumda, debugPrint () kodunu yorumladığımda, sonuç dizesiyle hiçbir şey yapılmamasına rağmen, sunucunun debugPrint () öğesine yapılan her çağrıdaki tüm değişkenleri birleştirme sorununu yaşaması gerekir. Ancak, varargs kullanırsanız, sunucu sadece onlara ihtiyaç olmadığını fark önce bir diziye koymak zorunda. Çok zaman kazandırır.
Varargs, bir yöntemde iletilecek argüman sayısından emin olmadığımızda kullanılabilir. Arka planda belirtilmemiş uzunlukta bir parametre dizisi oluşturur ve böyle bir parametre çalışma zamanında dizi olarak ele alınabilir.
Farklı sayıda parametreyi kabul etmek için aşırı yüklenmiş bir yöntemimiz varsa, yöntemi farklı zamanlarda aşırı yüklemek yerine, varargs konseptini kullanabiliriz.
Ayrıca parametrelerin tipi değiştiğinde "Object ... test" kullanılması kodu çok basitleştirecektir.
Örneğin:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
Burada dolaylı olarak int tipi (list) bir dizi parametre olarak geçirilir ve kodda bir dizi olarak ele alınır.
Daha iyi bir anlayış için bu bağlantıyı takip edin (bu kavramı açıkça anlamamda bana çok yardımcı oldu): http://www.javadb.com/using-varargs-in-java
Not: Ben bile bilmiyordum varargs kullanmak korkuyordu. Ama şimdi alışkınım. Söylendiği gibi: "Bilinmeyene korkan, bilinene sarılıyoruz", bu yüzden mümkün olduğunca çok kullanın ve siz de beğenmeye başlayacaksınız :)
Varargs, java sürüm 1.5'te eklenen özelliktir.
Bunu neden kullanmalıyım?
Bu nasıl çalışır?
Verilen bağımsız değişkenlerle bir dizi oluşturur ve diziyi yönteme iletir.
Misal :
public class Solution {
public static void main(String[] args) {
add(5,7);
add(5,7,9);
}
public static void add(int... s){
System.out.println(s.length);
int sum=0;
for(int num:s)
sum=sum+num;
System.out.println("sum is "+sum );
}
}
Çıktı :
2
toplam 12
3
toplam 21
Ben de varargs ile ilgili bir korkum var:
Arayan, yönteme açık bir dizi geçirirse (birden çok parametrenin aksine), bu diziye paylaşılan bir başvuru alırsınız.
Bu diziyi dahili olarak depolamanız gerekiyorsa, arayanın daha sonra değiştirebilmesini önlemek için önce diziyi kopyalamak isteyebilirsiniz.
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
Bu durum, durumu daha sonra değişebilecek herhangi bir nesne türünden geçmekten gerçekten farklı olmasa da, dizi genellikle (bir dizi yerine birden çok bağımsız değişkeni olan bir çağrı durumunda) derleyici tarafından dahili olarak oluşturulan ve güvenli bir şekilde oluşturabileceğiniz yeni bir nesne kullanın, bu kesinlikle beklenmedik bir davranış.
Bir tür filtre nesnesi alabilen kurucular için varargs sık kullanıyorum. Örneğin, Hadoop tabanlı sistemimizin büyük bir kısmı, JSON'a öğelerin serileştirilmesini ve serileştirilmesini işleyen ve her birinin bir içerik öğesi alıp değiştiren veya döndüren veya null döndüren bir dizi işlemciyi uygulayan bir Eşleyici'ye dayanır. reddetmek.
Var-Args'ın Java belgesinde var arglerin kullanımı oldukça açıktır:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
kullanım hakkında diyor:
"Peki ne zaman varargs kullanmalısınız? Bir istemci olarak, API her sunduğunda bunlardan yararlanmalısınız. Temel API'lardaki önemli kullanımlar yansıma, mesaj biçimlendirme ve yeni printf özelliğini içerir. Bir API tasarımcısı olarak bunları kullanmalısınız Genel olarak konuşursak, bir varargs yöntemini aşırı yüklememelisiniz, yoksa programcıların hangi aşırı yüklemenin çağrıldığını anlaması zor olacaktır. "