Java, 3 точки в параметрах - PullRequest
740 голосов
/ 01 июля 2010

Что означают 3 точки в следующем методе?

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

Ответы [ 9 ]

893 голосов
/ 01 июля 2010

Это означает, что ноль или более объектов String (или их массив) могут быть переданы в качестве аргументов для этого метода.

См. Раздел «Произвольное количество аргументов» здесь: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

В вашем примере вы могли бы назвать его следующим:

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

Важное примечание: Аргумент (ы), передаваемый таким образом, всегдамассив - даже если есть только один.Обязательно обращайтесь с этим таким образом в теле метода.

Важное примечание 2: Аргумент, который получает ..., должен быть последним в сигнатуре метода.Итак, myMethod(int i, String... strings) в порядке, но myMethod(String... strings, int i) не в порядке.

Спасибо Vash за разъяснения в своем комментарии.

110 голосов
/ 01 июля 2010

Эта функция называется varargs , и это функция, представленная в Java 5. Это означает, что функция может принимать несколько String аргументов:

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

Затем вы можете использоватьString var в виде массива:

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

Этот ответ в значительной степени заимствует у Кишвы и Лоренцо ..., а также из комментария Графена.

14 голосов
/ 30 января 2017

Это Varargs :)

Varargs, короткий для аргументов переменной длины, является функцией, которая позволяет методу принимать переменное число аргументов (ноль или более).С помощью varargs стало проще создавать методы, которые должны принимать переменное число аргументов.Функция переменного аргумента была добавлена ​​в Java 5.

Синтаксис varargs

vararg защищен тремя многоточиями (три точки) после типа данных, егообщая форма:

return_type method_name(data_type ... variableName){
}  

Потребность в varargs

До Java 5, в случае, когда требовалось переменное количество аргументов, было два способа обработкиit

Если максимальное количество аргументов, которое может принять метод, было небольшим и известным, то могут быть созданы перегруженные версии метода.Если максимальное количество аргументов, которое может принять метод, было большим или неизвестным, тогда подход состоял в том, чтобы поместить эти аргументы в массив и передать их методу, который принимает массив в качестве параметра.Эти 2 подхода были подвержены ошибкам - каждый раз создавался массив параметров и их было трудно поддерживать - поскольку добавление нового аргумента может привести к написанию нового перегруженного метода.

Преимущества varargs

Предлагает гораздо более простой вариант.Меньше кода, так как нет необходимости писать перегруженные методы.

Пример 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

Из программы видно, что длина используется здесь, чтобы найти числоаргументов, передаваемых в метод.Это возможно, потому что varargs неявно передаются в виде массива.Независимо от того, какие аргументы передаются как varargs, они хранятся в массиве, на который ссылается имя, данное varargs.В этой программе имя массива есть значения.Также обратите внимание, что метод вызывается с другим количеством аргументов, сначала вызывается с четырьмя аргументами, затем с тремя аргументами, а затем с нулевым аргументом.Все эти вызовы обрабатываются одним и тем же методом, который принимает varargs.

Ограничение с помощью varargs

В методе могут быть другие параметры с параметром varargs, однако вв этом случае параметр varargs должен быть последним параметром, объявленным методом.

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

Другое ограничение для varargs заключается в том, что должен быть только один параметр varargs.

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

Перегрузка методов varargs

Возможно перегрузить метод, который принимает параметр varargs.Метод Varargs может быть перегружен с помощью -

Типы его параметров vararg могут быть разными.Добавляя другие параметры.Пример перегрузки метода 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 

Переменные и неоднозначность перегрузки

В некоторых случаях вызов может быть неоднозначным, пока мы перегружаем метод 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 + " ");
  }
 }

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

В этой программе, когда мы вызываем метод displayData () без какого-либо параметра, он выдает ошибку, поскольку компилятор не уверен, предназначен ли этот метод для displayData(String ... values) или * 1064.*

Таким же образом, если у нас есть перегруженные методы, где у одного есть метод vararg одного типа, а у другого метода есть один параметр и vararg параметр того же типа, то у нас также есть неоднозначность - как Exp- displayData(int ... values) и displayData(int a, int ... values)

Эти два перегруженных метода всегда будут иметь неоднозначность.

12 голосов
/ 01 июля 2010

Это способ передачи Java varargs (аргументы переменного числа).

Если вы знакомы с C, это похоже на синтаксис ..., используемый в функции printf:

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

но в безопасном для типов виде: каждый аргумент должен соответствовать указанному типу (в вашем примере все они должны быть String).

Это простой пример того, как вы можете использовать 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");
   }
}

Аргумент ... на самом деле является массивом, поэтому вы можете передать String[] в качестве параметра.

11 голосов
/ 11 мая 2012

Возможно, это пример синтаксического сахара, так как он в любом случае реализован в виде массива (что не означает, что он бесполезен) - я предпочитаю передавать массив, чтобы сохранить его ясность, а также объявлять методы с массивами данного типа,Но скорее мнение, чем ответ.

4 голосов
/ 05 января 2017

Также, чтобы пролить свет, важно знать, что параметры var-arg ограничены одним, и вы не можете иметь несколько параметров var-art. Например, это нелегально:

public void myMethod(String... strings, int ... ints){
// method body
}
4 голосов
/ 29 июня 2014

Просто подумайте об этом как о ключевом слове params в C #, если вы исходите из этого фона :)

1 голос
/ 19 сентября 2017

String... совпадает с 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 голос
/ 28 февраля 2016

Действительно распространенный способ увидеть наглядный пример использования трех точек, присутствующих в одном из самых известных методов в Android AsyncTask (который сегодня используется не слишком часто из-за RXJAVA, не говоря уже о компонентах архитектуры Google), вы можете найти тысячи примеров, ищущих этот термин, и лучший способ понять и никогда не забывать о значении этих трех точек состоит в том, что они выражают ... сомнение ... так же, как на общем языке. А именно, не ясно, сколько параметров должно быть передано, может быть 0, может быть 1, может быть больше (массив) ...

...