Что означают три точки в следующем методе?
public void myMethod(String... strings){
// method body
}
Что означают три точки в следующем методе?
public void myMethod(String... strings){
// method body
}
Это означает, что в качестве аргумента (ов) для этого метода могут быть переданы ноль или более объектов 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)
не в порядке.
Спасибо Вашу за разъяснения в его комментарии.
Эта функция называется 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]
}
}
Этот ответ сильно заимствован из кисвы и Лоренцо... а также из комментария Графана.
Это способ 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[]
в качестве параметра.
Возможно, это пример синтаксического сахара, поскольку он реализован как массив в любом случае (это не значит, что это бесполезно). Я предпочитаю передавать массив, чтобы он был ясен, а также объявлять методы с массивами заданного типа, Скорее, мнение, чем ответ.
Это Varargs :)
Короткие аргументы varargs для аргументов переменной длины - это функция, которая позволяет методу принимать переменное количество аргументов (ноль или более). С помощью varargs стало проще создавать методы, которые должны принимать переменное количество аргументов. Функция переменной аргумента добавлена в Java 5.
Синтаксис varargs
Параметр vararg разделяется на три эллипса (три точки) после типа данных, его общий вид
return_type method_name(data_type ... variableName){
}
Потребность в варгарах
До появления Java 5 в случае необходимости переменного количества аргументов было два способа справиться с этим
Если максимальное количество аргументов, метод может принимать, был мал и известен, то могут быть созданы перегруженные версии метода. Если максимальное количество аргументов, которые мог бы принять метод, было большим или/и неизвестным, то подход заключался в том, чтобы поместить эти аргументы в массив и передать их методу, который принимает массив в качестве параметра. Эти два подхода были подвержены ошибкам - каждый раз создавали массив параметров и их трудно поддерживать, поскольку добавление нового аргумента может привести к написанию нового перегруженного метода.
Преимущества варгаров
Предлагает гораздо более простой вариант. Меньше кода, так как нет необходимости писать перегруженные методы.
Пример 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
одного типа, а другой метод имеет один параметр и параметр vararg
того же типа, то также мы имеем двусмысленность - как Exp - displayData(int... values)
и displayData(int a, int... values)
Эти два перегруженных метода всегда будут иметь двусмысленность.
Также, чтобы пролить некоторый свет, важно знать, что параметры var-arg ограничены одним, и вы не можете иметь несколько параметров var-art. Например, это нелогично:
public void myMethod(String... strings, int ... ints){
// method body
}
Подумайте об этом как ключевое слово params
в С#, если вы исходите из этого фона:)
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 Architecture), вы можете найти тысячи примеров, ищущих этот термин, и лучший способ понять и никогда не забывать о значении три точки - это то, что они выражают... сомнение... точно так же, как на общем языке. А именно, неясно, сколько параметров должно быть передано, может быть 0, может быть 1 может быть больше (массив)...