it-swarm.com.ru

Java, 3 точки в параметрах

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

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

Это означает, что ноль или более объектов 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 за разъяснения в своем комментарии.

885
kiswa

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

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

Затем вы можете использовать переменную String в качестве массива:

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

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

110
Cristian

Это Вараргс:)

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

Синтаксис varargs

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

return_type method_name(data_type ... variableName){
}  

нужно для varargs

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

Если максимальное количество аргументов, которое может принять метод, было небольшим и известным, то могут быть созданы перегруженные версии метода. Если максимальное количество аргументов, которое может принять метод, было большим или неизвестным, тогда подход состоял в том, чтобы поместить эти аргументы в массив и передать их методу, который принимает массив в качестве параметра. Эти 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 и перегрузка неоднозначность

В некоторых случаях вызов может быть неоднозначным, пока мы перегружаем метод 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) или displayData(int ... values)

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

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

14
SIW

Это 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[] в качестве параметра.

12
lornova

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

11
MichaelS

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

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

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

4
Ε Г И І И О

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

1
trocchietto

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
Uddhav Gautam