Java, parametrelerde 3 nokta


822

Aşağıdaki yöntemdeki 3 nokta ne anlama geliyor?

public void myMethod(String... strings){
    // method body
}

Yanıtlar:


987

Bu, sıfır veya daha fazla String nesnesinin (veya bunların bir dizisinin) bu yöntem için bağımsız değişken olarak geçirilebileceği anlamına gelir.

Buradaki "Rasgele Bağımsız Değişken Sayısı" bölümüne bakın: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

Örneğinizde, aşağıdakilerden herhangi biri olarak adlandırabilirsiniz:

myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});

Önemli Not: Bu şekilde iletilen argüman (lar) her zaman bir dizidir - sadece bir tane olsa bile. Yöntem gövdesinde bu şekilde davrantığınızdan emin olun.

Önemli Not 2: Bu yöntemi alan bağımsız değişken ..., yöntem imzasında sonuncu olmalıdır. Yani,myMethod(int i, String... strings) tamam, ama myMethod(String... strings, int i)iyi değil.

Yorumundaki açıklamalar için Vash'e teşekkürler.


112
Yanılıyorsunuz, bu "bir veya daha fazla", varargs ile 0 veya daha fazla belirtebiliriz ve bu her zaman yöntemdeki son parametre olmalıdır. Yöntem X (String ... parametreler) x () veya yöntem y (String bebek arabası, dize ... parametreler) çağrı olabilir çağrı olabilir y ( "1") olarak
Vash - Damian Leszczyński

2
Keşke bu da işe yararsa. myMethod ("bir", "iki", "üç", yeni Dize [] {"a", "b", "c" "});
2sb

2
Yöntem 0 parametrelerini neden verebilirsiniz? Bu büyük olasılıkla ArrayIndexOutOfBoundsException yol açar. Şimdi her zaman bu durumu göz önünde bulundurmalısınız.
Olle Söderström

11
Çünkü isteğe bağlıdırlar. Sıfır veya daha fazlasına sahip olmak için yöntemi düzgün bir şekilde uygulamak için isteğe bağlı argümanlar kullanmaya karar veren geliştiriciye bağlıdır.
kiswa

@ OlleSöderström Bir başka neden de, resmi parametrenin derleme zamanında bir dizi haline dönüştürülmesidir. Bu, bir diziye geçmenin aynı sonucu verdiği anlamına gelir. Bir dizinin uzunluğu derleme zamanında bilinmediğinden, en az bir öğeyi geçirme kısıtlaması basitçe çağrılarak atlanabilir someMethod(new SomeType[] { }). Bu bir hack olurdu, değil mi?
MC İmparatoru

124

Bu özelliğe varargs denir ve Java 5'de tanıtılan bir özelliktir. Bu, işlevin birden çok Stringbağımsız değişken alabileceği anlamına gelir :

myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass an array

Ardından, Stringvar olanı dizi olarak kullanabilirsiniz :

public void myMethod(String... strings){
    for(String whatever : strings){
        // do what ever you want
    }

    // the code above is is equivalent to
    for( int i = 0; i < strings.length; i++){
        // classical for. In this case you use strings[i]
    }
}

Bu cevap, kiswa ve Lorenzo'dan ... ve ayrıca Graphain'in yorumundan büyük ölçüde ödünç alıyor.


13
Kod bayt koduna çarptığında , bir dizidir. Diğer her şey sadece derleyici tarafından desteklenen sözdizimidir.
Donal Fellows

Bu cevap, düzenlemeleri doğru okuduğumda kiswa ve Lorenzo'dan büyük ödünç alır.
Matt Mitchell

3
@Greph, cevabınızı düzenlemek ve onu yalnız bırakmaktan daha doğru yapmak daha iyidir. Ve eğer başka bir cevap sizin gelişmenizin kaynağıysa, o zaman gider. En azından bu konuda dürüst (ve sanırım ona yardımcı olan diğer cevapları iptal etti ...)?

1
@ Yeterince iyi olduğunu belirttikten sonra dürüst olacak. Baktığın için teşekkürler.
Matt Mitchell

23

Bu Varargs :)

Değişken uzunluklu argümanlar için varargs short, yöntemin değişken sayıda argümanı (sıfır veya daha fazla) kabul etmesini sağlayan bir özelliktir. Varargs ile değişken sayıda argüman alması gereken yöntemler oluşturmak basitleşti. Değişken bağımsız değişkeninin özelliği Java 5'te eklenmiştir.

Varargs sözdizimi

Bir vararg veri tipinden sonra üç üç nokta (üç nokta) ile ayrılır, genel şekli

return_type method_name(data_type ... variableName){
}  

Varargs ihtiyacı

Java 5'ten önce, değişken sayıda bağımsız değişkene ihtiyaç duyulması durumunda, bunu işlemek için iki yol vardı

Maksimum bağımsız değişken sayısı, bir yöntemin alabileceği küçük ve biliniyorsa, yöntemin aşırı yüklenmiş sürümleri oluşturulabilir. Bir yöntemin alabileceği maksimum bağımsız değişken sayısı büyük veya / ve bilinmiyorsa, yaklaşım bu bağımsız değişkenleri bir diziye koymak ve diziyi parametre olarak alan bir yönteme aktarmaktı. Bu iki yaklaşım hataya yatkındır - her seferinde bir dizi parametre oluşturmak ve bakımı zordur - çünkü yeni argümanın eklenmesi yeni bir aşırı yüklenmiş yöntem yazılmasına neden olabilir.

Varargs'ın avantajları

Çok daha basit bir seçenek sunar. Aşırı yüklenmiş yöntemler yazmaya gerek olmadığından daha az kod.

Varargs örneği

public class VarargsExample {
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 public static void main(String[] args) {
  VarargsExample vObj = new VarargsExample();
  // four args
  vObj.displayData("var", "args", "are", "passed");
  //three args
  vObj.displayData("Three", "args", "passed");
  // no-arg
  vObj.displayData();
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 
Number of arguments passed 3
Three 
args 
passed 
Number of arguments passed 0

Programdan, yönteme iletilen argüman sayısını bulmak için burada uzunluğun kullanıldığı görülebilir. Bu mümkündür, çünkü varargs dolaylı olarak bir dizi olarak geçirilir. Varargs olarak iletilen argümanlar varargs'a verilen adla belirtilen bir dizide saklanır. Bu programda dizi adı değerlerdir. Ayrıca, yöntemin farklı sayıda argümanla çağrıldığını, önce dört argümanla, daha sonra üç argümanla ve ardından sıfır argümanla çağrıldığını unutmayın. Tüm bu çağrılar varargs alan aynı yöntemle işlenir.

Varargs ile kısıtlama

Bir yöntemde varargs parametresi ile başka parametrelerin olması da mümkündür, ancak bu durumda varargs parametresi yöntem tarafından bildirilen son parametre olmalıdır.

void displayValues(int a, int b, int  values) // OK
   void displayValues(int a, int b, int  values, int c) // compiler error

Varargs ile ilgili bir diğer kısıtlama, sadece bir varargs parametresi olması gerektiğidir.

void displayValues(int a, int b, int  values, int  moreValues) // Compiler error

Aşırı Yük varargs Yöntemleri

Varargs parametresini alan bir yöntemi aşırı yüklemek mümkündür. Varargs yöntemi aşırı yüklenebilir -

Vararg parametresinin türleri farklı olabilir. Başka parametreler ekleyerek. Aşırı yük varargs yöntemi örneği

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 // Method with int vararg and one more string parameter
 public void displayData(String a, int ... values){
  System.out.println(" a " + a);
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // One String param and two int args
  vObj.displayData("Test", 20, 30);
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 

Number of arguments passed 2
10 
20

 a Test
Number of arguments passed 2
20 
30 

Varargs ve aşırı yükleme belirsizliği

Bazı durumlarda varargs yöntemini aşırı yüklerken çağrı belirsiz olabilir. Bir örnek görelim

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // This call is ambiguous
  vObj.displayData();
 }
}

Bu programda, herhangi bir parametre olmadan displayData () yöntemine çağrı yaptığımızda hata atar, çünkü derleyici bu yöntem çağrısının displayData(String ... values)veyadisplayData(int ... values)

Aynı şekilde vararg, birinin bir tipin metoduna sahip olduğu ve başka bir yöntemin varargaynı tipte bir parametre ve parametrenin bulunduğu aşırı yüklenmiş yöntemler varsa , aynı zamanda belirsizliğe sahibiz - As Exp - displayData(int ... values)vedisplayData(int a, int ... values)

Bu iki aşırı yüklenmiş yöntem her zaman belirsizliğe sahip olacaktır.


15

Bu varargs (değişken sayı argümanları) geçirmenin Java yoludur .

C'yi biliyorsanız, bu işlevde ...kullanılan sözdizimine benzer printf:

int printf(const char * format, ...);

ancak güvenli bir şekilde: her argüman belirtilen türe uymak zorundadır (örneğinizde hepsi olmalıdır String).

Bu, varargs'ı nasıl kullanabileceğinizin basit bir örneğidir :

class VarargSample {

   public static void PrintMultipleStrings(String... strings) {
      for( String s : strings ) {
          System.out.println(s);
      }
   }

   public static void main(String[] args) {
      PrintMultipleStrings("Hello", "world");
   }
}

...Eğer bir geçebileceği böylece argüman, aslında bir dizidir String[]parametre olarak.


11

Tartışmalı olarak, sözdizimsel şekerin bir örneğidir, çünkü yine de bir dizi olarak uygulanmaktadır (bu işe yaramaz anlamına gelmez) - Açık tutmak için bir dizi geçirmeyi tercih ederim ve aynı zamanda verilen tipteki dizilerle yöntemler bildiririm. Bir cevaptan ziyade bir görüş.


5

Ayrıca biraz ışık tutmak için var-arg parametrelerinin biriyle sınırlı olduğunu ve birkaç var-art parametresine sahip olamayacağınızı bilmek önemlidir. Örneğin bu illigal:

public void myMethod(String... strings, int ... ints){
// method body
}


2

Android AsyncTask'taki en ünlü yöntemlerden birinde bulunan üç noktanın kullanımının açık bir örneğini görmenin gerçekten yaygın bir yolu (bugün RXJAVA nedeniyle çok fazla kullanılmıyor, Google Mimarlık bileşenlerinden bahsetmiyoruz), bu terimi arayan binlerce örnek bulabilirsiniz ve artık üç noktanın anlamını anlamak ve asla unutmamak için en iyi yol, tıpkı ortak dilde olduğu gibi ... bir şüphe ifade etmeleridir. Yani geçilmesi gereken parametrelerin sayısı belli değil, 0 olabilir, 1 olabilir daha fazla olabilir (bir dizi) ...


1

String... aynıdır String[]

import java.lang.*;

public class MyClassTest {

    //public static void main(String... args) { 

    public static void main(String[] args) {
        for(String str: args) {
            System.out.println(str);
        }
    }
}

1
Eğer String...aynıysa String[], bunu söyleyemez miydin?
Scott Hunter

8
Teknik olarak doğru değildir, çünkü String[]bir argüman gerektirir (en azından boş bir dizi), oysa String...öyle değildir (yukarıdaki cevaba bakınız).
Aurel

0

Diğer iyi yazılmış cevaplara ek olarak, varagrsyararlı bulduğum bir avantajı, dizi ile bir yöntemi parametre türü olarak çağırdığımda, bir dizi oluşturma acısını ortadan kaldırmasıdır; öğeleri ekleyin ve gönderin. Bunun yerine, yöntemi istediğim kadar çok değerle çağırabilirim; sıfırdan çoğuna.


0
  • Aynı veri tipinde sıfır veya çoklu parametre anlamına gelir.
  • Yapıcı veya işlevin son parametresi olmalıdır.
  • İlgili yapıcı veya işlevde bu tür parametrelerden yalnızca birine sahip olabiliriz.

Örnek 1:

public class quest1 {

    public quest1(String... mynum) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1();

        quest1 q1=new quest1("hello");

    }
}

Örnek 2:

public class quest1 {

    public quest1(int... at) {
        System.out.println("yee haa");
    }

    public quest1(String... at) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1("value");

        quest1 q1=new quest1(1);

    }

    public void name(String ... s) {

    }
}

çıktı:

evet haa

evet haa


-1

Sözdizimi: (Üçlü nokta ...) -> Bağımsız değişkenlere sıfır veya daha fazla nesne ekleyebileceğimiz veya bir tür nesne dizisi geçirebileceğimiz anlamına gelir.

public static void main(String[] args){}
public static void main(String... args){}

Tanım: 1) Nesne ... argümanı sadece bir Nesne dizisine referanstır.

2) ('String []' veya String ...) Herhangi bir sayıda dize nesnesini işleyebilir. Dahili olarak bir referans türü nesnesi dizisi kullanır.

i.e. Suppose we pass an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:

3) Yöntemi tek bir bağımsız değişkenle çağırmak istiyorsanız ve bu bir dizi olduğunda, bunu açıkça sarmanız gerekir

another. method(new Object[]{array}); 
OR 
method((Object)array), which will auto-wrap.

Uygulama: Argüman sayısı dinamik olduğunda (çalışma zamanında bilen argüman sayısı) ve geçersiz kılmada kullanılır. Genel kural - Yöntemde herhangi bir tür ve herhangi bir sayıda argüman iletebiliriz. Belirli argümanların önüne nesne (...) argümanları ekleyemeyiz. yani

void m1(String ..., String s) this is a wrong approach give syntax error.
void m1(String s, String ...); This is a right approach. Must always give last order prefernces.   
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.