Java, 3 titik dalam parameter

822

Apa arti 3 titik dalam metode berikut?

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

Jawaban:

987

Ini berarti bahwa nol atau lebih objek String (atau array dari mereka) dapat dilewatkan sebagai argumen untuk metode itu.

Lihat bagian "Jumlah Argumen Sewenang-wenang" di sini: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

Dalam contoh Anda, Anda dapat menyebutnya sebagai salah satu dari yang berikut:

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

Catatan Penting: Argumen yang disampaikan dengan cara ini selalu berupa array - meskipun hanya ada satu. Pastikan Anda memperlakukannya seperti itu di tubuh metode.

Catatan Penting 2: Argumen yang mendapatkan ...harus menjadi yang terakhir dalam tanda tangan metode. Jadi, myMethod(int i, String... strings)tidak apa-apa, tetapi myMethod(String... strings, int i)tidak baik.

Terima kasih kepada Vash untuk klarifikasi dalam komentarnya.

Kiswa
sumber
112
Anda salah, dalam "satu atau lebih" itu, dengan varargs kita dapat menentukan 0 atau lebih, dan ini harus selalu menjadi parameter terakhir dalam metode. Metode x (String ... params) dapat dipanggil sebagai x () atau metode y (String pram, String ... params) dapat dipanggil sebagai y ("1")
Damian Leszczyński - Vash
2
Saya berharap jika ini akan berhasil juga. myMethod ("satu", "dua", "tiga", String baru [] {"a", "b", "c" "});
2sb
2
Mengapa Anda diizinkan memberikan parameter metode 0? Itu kemungkinan besar akan mengarah ke ArrayIndexOutOfBoundsException. Sekarang Anda harus selalu mempertimbangkan kasus itu.
Olle Söderström
11
Karena mereka opsional. Terserah pengembang yang memutuskan untuk menggunakan argumen opsional untuk menerapkan metode dengan benar untuk memiliki nol atau lebih dari itu.
Kiswa
@ OlleSöderström Alasan lain adalah parameter formal dikonversi menjadi array pada waktu kompilasi. Itu berarti bahwa meneruskan array menghasilkan hasil yang sama. Karena panjang array tidak diketahui pada waktu kompilasi, batasan untuk melewatkan setidaknya satu elemen dapat dilewati hanya dengan memanggil someMethod(new SomeType[] { }). Itu akan menjadi retasan, bukan?
MC Kaisar
124

Fitur itu disebut varargs , dan ini fitur yang diperkenalkan di Java 5. Ini artinya fungsi itu bisa menerima banyak Stringargumen:

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

Kemudian, Anda bisa menggunakan Stringvar sebagai array:

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

Jawaban ini sangat dipinjam dari kiswa dan Lorenzo ... dan juga dari komentar Graphain.

Cristian
sumber
13
Ketika kode menyentuh bytecode, itu adalah array. Yang lainnya adalah sintaks yang didukung hanya oleh kompiler.
Donal Fellows
Jawaban ini sangat meminjam dari Kiswa dan Lorenzo jika saya membaca suntingan dengan benar.
Matt Mitchell
3
@Graf 'lebih baik mengedit jawaban Anda dan membuatnya lebih benar daripada membiarkannya sendirian. Dan jika jawaban lain adalah sumber peningkatan Anda, begitulah. Setidaknya dia jujur ​​tentang hal itu (dan saya berasumsi dia mengangkat jawaban lain yang membantunya ... kan?)
1
@Apakah dia jujur ​​setelah saya tunjukkan mana yang cukup baik. Terima kasih telah melihat.
Matt Mitchell
23

Ini Varargs :)

Varargs pendek untuk argumen panjang variabel adalah fitur yang memungkinkan metode untuk menerima jumlah variabel argumen (nol atau lebih). Dengan varargs, menjadi mudah untuk membuat metode yang perlu mengambil sejumlah variabel argumen. Fitur argumen variabel telah ditambahkan di Java 5.

Sintaks dari varargs

Sebuah vararg dipisahkan oleh tiga elipsis (tiga titik) setelah tipe data, bentuk umumnya adalah

return_type method_name(data_type ... variableName){
}  

Perlu untuk varargs

Sebelum Java 5, jika ada kebutuhan jumlah variabel argumen, ada dua cara untuk mengatasinya

Jika jumlah argumen maksimal, suatu metode dapat dianggap kecil dan diketahui, maka versi yang berlebihan dari metode tersebut dapat dibuat. Jika jumlah maksimum argumen yang bisa diambil suatu metode adalah besar atau / dan tidak diketahui maka pendekatannya adalah untuk menempatkan argumen-argumen itu dalam sebuah array dan meneruskannya ke sebuah metode yang menggunakan array sebagai parameter. Kedua pendekatan ini rawan kesalahan - membangun array parameter setiap saat dan sulit dipertahankan - karena penambahan argumen baru dapat menghasilkan penulisan metode kelebihan beban baru.

Keuntungan varargs

Menawarkan opsi yang lebih sederhana. Lebih sedikit kode karena tidak perlu menulis metode kelebihan beban.

Contoh varargs

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

Dapat dilihat dari program bahwa panjang digunakan di sini untuk menemukan jumlah argumen yang diteruskan ke metode. Ini dimungkinkan karena varargs secara implisit dilewatkan sebagai sebuah array. Argumen apa pun yang dilewatkan sebagai vararg disimpan dalam array yang disebut dengan nama yang diberikan kepada varargs. Dalam program ini nama array adalah nilai. Perhatikan juga bahwa metode dipanggil dengan jumlah argumen yang berbeda, panggilan pertama dengan empat argumen, kemudian tiga argumen dan kemudian dengan argumen nol. Semua panggilan ini ditangani dengan metode yang sama yang mengambil varargs.

Batasan dengan varargs

Dimungkinkan untuk memiliki parameter lain dengan parameter varargs dalam suatu metode, namun dalam kasus itu, parameter varargs harus menjadi parameter terakhir yang dideklarasikan oleh metode tersebut.

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

Pembatasan lain dengan varargs adalah bahwa harus ada hanya satu parameter varargs.

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

Metode overloading varargs

Dimungkinkan untuk membebani metode yang menggunakan parameter varargs. Metode Varargs dapat kelebihan beban oleh -

Jenis parameter varargnya bisa berbeda. Dengan menambahkan parameter lainnya. Contoh metode overloading varargs

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 

Kerancuan dan ambiguitas yang berlebihan

Dalam beberapa kasus, panggilan mungkin tidak jelas sementara kami memiliki metode vararg yang kelebihan beban. Mari kita lihat sebuah contoh

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

Dalam program ini ketika kita melakukan panggilan ke metode displayData () tanpa parameter apa pun ia melempar kesalahan, karena kompiler tidak yakin apakah panggilan metode ini untuk displayData(String ... values)ataudisplayData(int ... values)

Cara yang sama jika kita memiliki metode kelebihan beban di mana seseorang memiliki varargmetode satu jenis dan metode lain memiliki satu parameter dan varargparameter dari jenis yang sama, maka juga kita memiliki ambiguitas - Sebagai Exp - displayData(int ... values)dandisplayData(int a, int ... values)

Kedua metode kelebihan beban ini akan selalu memiliki ambiguitas.

SIW
sumber
15

Ini adalah cara Java untuk melewatkan varargs (argumen nomor variabel).

Jika Anda terbiasa dengan C, ini mirip dengan ...sintaks yang digunakan printffungsinya:

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

tetapi dengan jenis yang aman: setiap argumen harus sesuai dengan jenis yang ditentukan (dalam sampel Anda, semuanya harus String).

Ini adalah contoh sederhana tentang bagaimana Anda dapat menggunakan varargs :

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

The ...Argumen ini sebenarnya sebuah array, sehingga Anda bisa melewati String[]sebagai parameter.

lornova
sumber
11

Dapat diperdebatkan, ini adalah contoh gula sintaksis, karena ini diterapkan sebagai array (yang tidak berarti itu tidak berguna) - Saya lebih suka melewatkan array untuk membuatnya tetap jelas, dan juga mendeklarasikan metode dengan array dari tipe yang diberikan. Namun, lebih merupakan opini daripada jawaban.

Michael
sumber
5

Juga untuk menjelaskan, penting untuk mengetahui bahwa parameter var-arg terbatas pada satu dan Anda tidak dapat memiliki beberapa parar var-art. Misalnya ini tidak sah:

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

Anggap saja sebagai kata kunci paramsdalam C #, jika Anda berasal dari latar belakang itu :)

Ε Г И І И О
sumber
Saya seorang programmer C #.
Programmer Berorientasi Uang
2

Cara yang sangat umum untuk melihat contoh yang jelas tentang penggunaan tiga titik itu hadir dalam salah satu metode paling terkenal di android AsyncTask (yang saat ini tidak digunakan terlalu banyak karena RXJAVA, belum lagi komponen Arsitektur Google), Anda dapat menemukan ribuan contoh mencari istilah ini, dan cara terbaik untuk memahami dan tidak pernah melupakan lagi arti dari tiga titik adalah bahwa mereka mengekspresikan ... keraguan ... seperti dalam bahasa umum. Yaitu tidak jelas jumlah parameter yang harus dilewati, bisa 0, bisa 1 bisa lebih (array) ...

trocchietto
sumber
1

String... sama dengan 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);
        }
    }
}
Uddhav Gautam
sumber
1
Jika String...sama String[], tidak bisakah Anda mengatakannya begitu saja?
Scott Hunter
8
Secara teknis tidak benar karena String[]memerlukan argumen (setidaknya array kosong) sedangkan String...tidak (lihat jawaban di atas).
Aurel
0

Menambahkan ke jawaban yang ditulis dengan baik lainnya, keuntungan yang varagrssaya temukan berguna adalah bahwa, ketika saya memanggil metode dengan array sebagai tipe parameter, itu menghilangkan rasa sakit menciptakan array; tambahkan elemen lalu kirim. Sebagai gantinya, saya bisa memanggil metode dengan nilai sebanyak yang saya inginkan; dari nol ke banyak.

Referensi Phantom
sumber
0
  • Itu berarti nol atau beberapa parameter dari tipe data yang sama.
  • Itu harus menjadi parameter terakhir dari konstruktor atau fungsi.
  • Kami hanya dapat memiliki satu dari parameter tipe ini di konstruktor atau fungsi masing-masing.

Contoh 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");

    }
}

Contoh 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) {

    }
}

keluaran:

yee haa

yee haa

Shubham Jain
sumber
-1

Sintaks: (Titik tiga ...) -> Berarti kita dapat menambahkan nol atau lebih objek melewati argumen atau melewatkan array objek tipe.

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

Definisi: 1) Argumen Object ... hanyalah referensi ke array Objects.

2) ('String []' atau String ...) Ia dapat menangani sejumlah objek string. Secara internal ia menggunakan array objek tipe referensi.

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) Jika Anda ingin memanggil metode dengan satu argumen dan kebetulan array, Anda harus secara eksplisit membungkusnya dalam

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

Aplikasi: Terutama digunakan ketika jumlah argumen dinamis (jumlah argumen tahu saat runtime) dan dalam mengesampingkan. Aturan umum - Dalam metode ini kita dapat meneruskan semua jenis dan sejumlah argumen. Kami tidak dapat menambahkan argumen objek (...) sebelum argumen tertentu. yaitu

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.   
Vishal Sheth
sumber