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

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

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

9 ответов


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

см. раздел "произвольное количество аргументов" здесь: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) - это не нормально.

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


эта функция называется С 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]
    }
}

этот ответ сильно заимствует у Кисвы и Лоренцо... а также из замечания Graphain по.


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

если вы знакомы с C, это похоже на ... синтаксис использовал его в :

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


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


это с varargs :)

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

синтаксис varargs

С переменным числом аргументов является secified тремя точками (три точки) после типа данных его общая форма

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)

эти два перегруженных метода, всегда будет неопределенность.


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

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

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


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

        }
        }
        }

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