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


Ответы:


988

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


112
Вы ошибаетесь, в этом «один или несколько», с помощью varargs мы можем указать 0 или более, и это всегда должно быть последним параметром в методе. Метод x (String ... params) может быть вызван как x (), или метод y (String pram, String ... params) может быть вызван как y ("1")
— Дамиан Лещинский - Ваш

2
Я бы хотел, чтобы это тоже сработало. myMethod ("one", "two", "three", new String [] {"a", "b", "c" "});
— 2sb

2
Почему вам разрешено давать методу 0 параметров? Это, скорее всего, приведет к ArrayIndexOutOfBoundsException. Теперь вы всегда должны принимать это во внимание.
— Olle Söderström

11
Потому что они необязательны. Это зависит от разработчика, который решил использовать необязательные аргументы для правильной реализации метода, чтобы иметь ноль или более из них.
— Kiswa

@ OlleSöderström Другая причина заключается в том, что формальный параметр преобразуется в массив во время компиляции. Это означает, что передача в массиве дает тот же результат. Поскольку длина массива не известна во время компиляции, ограничение на прохождение хотя бы одного элемента можно обойти простым вызовом someMethod(new SomeType[] { }). Это было бы взломом, не так ли?
— MC Emperor

124

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

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

Затем вы можете использовать Stringvar в качестве массива:

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

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


13
Когда код попадает в байт - код, он является массивом. Все остальное синтаксис поддерживается только компилятором.
— Донал Феллоуз

Этот ответ в значительной степени заимствует у Кишвы и Лоренцо, если я правильно читаю правки.
— Мэтт Митчелл

3
@ Граф 'лучше отредактировать свой ответ и сделать его более правильным, чем оставить его в покое. И если другой ответ является источником вашего улучшения, значит, так и есть. По крайней мере, он честен в этом (и я предполагаю, что он проголосовал за другие ответы, которые помогли ему ... правильно?).

1
@ Будет ли он честен после того, как я это укажу, и это достаточно хорошо. Спасибо за поиск.
— Мэтт Митчелл

23

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

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

Синтаксис varargs

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

return_type method_name(data_type ... variableName){
}  

Потребность в варагс

До 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)

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


15

Это 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

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


5

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

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


2

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


1

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
Если String...это так же String[], не могли бы вы просто сказать это?
— Скотт Хантер

8
Технически это не так, потому что String[]требует аргумент (по крайней мере, пустой массив), тогда как String...нет (см. Ответ выше).
— Аурел

0

В дополнение к другим хорошо написанным ответам, преимущество, которое varagrsя нашел полезным, состоит в том, что, когда я вызываю метод с массивом в качестве типа параметра, он избавляет от необходимости создавать массив; добавить элементы, а затем отправить его. Вместо этого я могу просто вызвать метод с любым количеством значений; от нуля до многих.


0
  • Это означает ноль или несколько параметров одного типа данных.
  • Это должен быть последний параметр конструктора или функции.
  • Мы можем иметь только один параметр этого типа в соответствующем конструкторе или функции.

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

    }
}

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

    }
}

вывод:

да хаа

да хаа


-1

Синтаксис: (Тройная точка ...) -> Означает, что мы можем добавить ноль или более объектов, передаваемых в аргументах, или передавать массив объектов типа.

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

Определение: 1) Аргумент Object ... - это просто ссылка на массив объектов.

2) ('String []' или String ...) Может обрабатывать любое количество строковых объектов. Внутренне он использует массив объектов ссылочного типа.

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) Если вы хотите вызвать метод с одним аргументом, а он является массивом, вы должны явно обернуть его в

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

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

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.   
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.