До j2se1.4 было невозможно определить методы с переменными реальными параметрами в программах Java - потому что Java требует, чтобы число и типы реальных параметров (аргументы) и формальные параметры должны были сопоставлены один за другим, а количество формальных параметров фиксировалось при определении метода. Хотя один и тот же метод может быть предоставлен с различным количеством формальных параметров с помощью механизма перегрузки, это все еще не может достичь цели, позволяющего произвольно изменять количество параметров.
Тем не менее, семантика некоторых методов требует, чтобы они смогли принять переменное число фактических параметров - например, знаменитый основной метод должен иметь возможность принять все параметры командной строки в качестве фактических параметров, и количество параметров командной строки не может быть определена заранее.
Для этой проблемы традиционно, практика «использования массива для обертывания фактических параметров, которые необходимо пройти», обычно используется для борьбы с ним.
1. Оберните параметры в массив
Практика «обернуть фактические параметры с массивами» можно разделить на три шага: сначала определить параметр типа массива для этого метода; Затем при вызове генерируйте массив, содержащий все фактические параметры, которые должны быть переданы; Наконец, передайте этот массив в качестве реального параметра.
Этот подход может эффективно достичь цели «заставить метод принять параметры переменных», но форма при вызове не достаточно проста.
Механизм Varargs предоставляется в J2SE1.5, что позволяет прямое определение формальных параметров, которые могут соответствовать нескольким реальным параметрам. Таким образом, переменное количество фактических параметров может быть передано проще.
Значение arargs
Вообще говоря, «Varargs» означает «variablenumberfarguments». Иногда это просто называется «переменными», но, поскольку этот термин не указывает на то, что является переменным, значение немного расплывчато.
2. Определите метод с переменными реальными параметрами
Просто добавьте три последовательных "". (то есть «...», эллипсис в предложении на английском языке) между «типом» и «Имя параметра» формального параметра, и он может соответствовать неопределенному фактическому параметру. Метод с такими формальными параметрами - это метод с переменными реальными параметрами.
Листинг 1: метод с переменными реальными параметрами
private static int sumup (int ... values) {}Обратите внимание, что только последний формальный параметр может быть определен как «может соответствовать неопределенному фактическому параметру». Следовательно, в методе может быть только один такой формальный параметр. Кроме того, если этот метод имеет другие формальные параметры, поместите их в переднее положение.
Компилятор будет преобразовать последний формальный параметр в секретный параметр массива в секрете и сделает отметок в скомпилированном файле класса, чтобы указать, что это метод с переменными реальными параметрами.
Листинг 2: секретная форма метода с переменными реальными параметрами
Private Static Int Sumup (int [] values) {}Из -за таких преобразований невозможно определить метод для этого класса, который согласуется с конвертированной подписью метода.
Листинг 3: Комбинации, которые вызывают ошибки компиляции
Private Static int sumUp (int ... values) {} private static int sumUp (int [] values) {}3. Вызовите метод с переменным количеством реальных параметров
Пока фактические параметры, которые должны быть переданы, записаны один за другим в соответствующую позицию, можно вызвать метод с переменным числом реальных параметров. Никаких других шагов не требуется.
Листинг 4: Можно пройти несколько параметров
sumUp(1,3,5,7);
Косвенно компилятор преобразует этот процесс вызова в форму «массив, завернутого в фактические параметры»:
Листинг 5: тайно появляется создание массива
sumUp(newint[]{1,2,3,4});
Кроме того, упомянутый здесь «неопределенная» также включает ноль, поэтому такой вызов разумный:
Листинг 6: Вы также можете перенести нулевые фактические параметры
sumUp();
Эффект этого призывного метода, тайно преобразованного компилятором, эквивалентен этому:
Листинг 7: Ноль реальных аргументов соответствует пустым массивам
sumUp(newint[]{});
Обратите внимание, что прошлое прошло в это время, а не ноль. Это позволяет обрабатывать единую форму без необходимости обнаружения, к какой ситуации она принадлежит.
4. Обработайте фактические параметры с переменными числами
Метод обработки фактических параметров с переменной, в основном такой же, как метод массива обработки фактические параметры. Все фактические параметры сохраняются в массиве с тем же именем, что и формальные параметры. В соответствии с фактическими потребностями, после прочтения элементов в этом массиве, приготовления пары или приготовления пищи вы можете делать все, что захотите.
Список 8: Обработка полученных аргументов
private static int sumup (int ... values) {int sum = 0; for (int i = 0; i <values.length; i ++) {sum+= values [i]; } return sum;}5. Переайлив переменное количество параметров
Иногда после принятия набора параметров переменного числа их необходимо передавать в другой метод переменного числа. Поскольку количество фактических параметров, полученных во время кодирования, не может быть известно, практика «записать их один за другим в место, где они должны появляться», невозможно. Тем не менее, это не означает, что это невиновемая задача, потому что есть другой способ вызвать метод с переменными реальными параметрами.
В глазах компилятора J2SE1.5 метод с переменными реальными параметрами является особым случаем метода с массивом формальных параметров в конце. Поэтому поместите весь набор фактических параметров, которые будут переданы заранее в массив, а затем передайте этот массив в качестве последнего фактического параметра методу с переменным числом реальных параметров, что не вызовет никаких ошибок. С помощью этой функции пересылка может быть завершена гладко.
Листинг 9: пересылка полученных фактических параметров
открытый класс printfsample {public static void main (string [] args) {printout ("pi:%f e:%f/n", math.pi, math.e); } private static void printout (формат строки, объект ... args) {system.out.printf (format, args); }}6. Это массив? Не массив?
Хотя за кулисами компилятор будет преобразовать формальные параметры, которые могут соответствовать неопределенным реальным параметрам в формальные параметры массива; и он также может использовать массив для обертывания фактических параметров, а затем передать их методу с переменным числом реальных параметров; Однако это не означает, что нет никакой разницы между «формальными параметрами, которые могут соответствовать неопределенным реальным параметрам» и «формальные параметры массива».
Очевидное отличие состоит в том, что если вы называете метод, последний формальный параметр, это формальный параметр массива в форме метода с переменным числом реальных параметров, это приведет только к ошибке компиляции «не может».
Листинг 10: ошибка компиляции для "невозможного"
Частная статическая void testoverloading (int [] i) {system.out.println ("a");} public static void main (string [] args) {testoverloading (1, 2, 3); // Ошибка компиляции}По этой причине этот краткий метод вызовов не может быть непосредственно применен при вызове методов, которые поддерживают только обертывание фактических параметров с массивами (например, оставленные от сторонних дизайнов библиотеки для J2SE1.5).
Если вы не можете изменить исходный класс и добавить переменную версию количества параметров в метод, который будет вызван, и вы хотите принять этот краткий метод вызова, вы можете использовать методы реконструкции «Envureforeignmethod» и «InterviceLocalextension», чтобы приблизиться к цели.
7. Когда переменное количество аргументов сталкивается с общим
В J2SE1.5 был добавлен новый «универсальный» механизм, который может параметризовать тип при определенных условиях. Например, при написании класса тип формальных параметров метода может быть представлен идентификатором (например, T). Что касается того типа этот идентификатор представляет, он указан при генерации экземпляра этого класса. Этот механизм может быть использован для обеспечения более полного повторного использования кода и более строгой проверки типа времени компиляции.
Однако общий механизм не может использоваться с переменными числами формальных параметров. Если формальный тип параметра, который соответствует неопределенному аргументу, представлен идентификатором, компилятор выдаст ошибку «genericarraycreation».
Листинг 11: Когда Varargs встречает дженерики
private static void testvarargs (t ... args) {// ошибка компиляции}Причиной этого явления является неотъемлемое ограничение общего механизма в J2SE1.5 - экземпляр этого типа не может быть создан с помощью типа, представленного идентификатором. До того, как версия Java поддерживает без этого ограничения, в основном не было хорошего решения этой проблемы.
Тем не менее, традиционная практика «обертка с массивами» не подлежит этому ограничению.
Листинг 12: компилируемые обходные пути
private static void testvarargs (t [] args) {for (int i = 0; i <args.length; i ++) {System.out.println (args [i]); }}8. Проблемы выбора при перегрузке
Java поддерживает механизмы «перегрузки», позволяя многим различным методам в одном классе иметь только списки формальных параметров. Затем компилятор выбирает, какой метод выполнять на основе фактических параметров во время вызова.
Традиционные варианты в основном основаны на принципе «предпочтительны особых людей». Специальность метода зависит от количества условий, которые необходимо выполнить, чтобы он работал гладко. Чем больше вам нужны условия, тем более особенным он.
После введения механизма Varargs этот принцип все еще применяется, но проблемы, которые необходимо рассматривать, обогащаются - традиционно, среди различных версий перегруженного метода, только те, чьи морфологические параметры и реальные параметры точно такие же, имеют право на дальнейшее рассмотрение. Однако после введения механизма Varargs можно соответствовать обеим версиям, и в других аспектах нет разницы, просто один реальный параметр имеет фиксированное число, а другой реальный параметр имеет переменную номер.
В этом случае используемое правило определения заключается в том, что «версия с фиксированным количеством реальных параметров имеет приоритет над версией с переменным количеством реальных параметров».
Список 13: предпочтительны версии с фиксированным количеством реальных параметров
Если, по мнению компилятора, несколько методов имеют одинаковый приоритет, он будет застрять в состоянии, где он не может сделать выбор относительно того, какой метод вызовать. В этом случае он будет генерировать ошибку компиляции «ServiceEto, называемого именем метода Isambigigent», и терпеливо ждать некоторых модификаций, чтобы избежать прибытия нового исходного кода, который сбивает с толку.
После введения механизма Varargs эта ситуация, которая может привести к путанице, увеличилась немного больше. Например, могут быть две версии, которые могут соответствовать, что точно одинаково в других аспектах, и оба конфликта с переменными числами реальных параметров происходят.
Общедоступный класс перегрузки. j) {System.out.println ("b");} private static void testoverloading (int i, int ... more) {System.out.println ("c");}}Если, по мнению компилятора, несколько методов имеют одинаковый приоритет, он будет застрять в состоянии, где он не может сделать выбор относительно того, какой метод вызовать. В этом случае он будет генерировать ошибку компиляции «ServiceEto, называемого именем метода Isambigigent», и терпеливо ждать некоторых модификаций, чтобы избежать прибытия нового исходного кода, который сбивает с толку.
После введения механизма Varargs эта ситуация, которая может привести к путанице, увеличилась немного больше. Например, могут быть две версии, которые могут соответствовать, что точно одинаково в других аспектах, и оба конфликта с переменными числами реальных параметров происходят.
Список 14: Независимо от того, что компилятор трудно быть
Public Class перегрузки {public static void main (string [] args) {testoverloading (1, 2, 3); // ошибка компиляции} частная статическая void testoverloading (объект ... args) {}}Кроме того, поскольку в J2SE1.5 существует механизм «автобоксинг/автоматическая докладка», возможно, что обе версии могут соответствовать, а количество реальных параметров является переменным, а другие аспекты точно одинаковы. Просто один приемлемый реальный параметр является основным типом, в то время как другой приемлемым реальным параметром является конфликт между классом пакетов.
Листинг 15: Новые выпуски из автобоксинга/аутопробнока
Общедоступный класс перегрузки {public static void main (string [] args) {/* ошибка компиляции*/testoverloading (1, 2);/* или ошибка компиляции*/testoverloading (new Integer (1), New Integer (2));} private static void -testoverling (int ... args) {} private void void testoverding integer integer integer integer inte -argeger integer inte -argegering ...9. Резюме
По сравнению с методом «Обернутый с массивами» реальный метод с переменными реальными параметрами проще и имеет более четкие значения при вызове. Однако этот механизм также имеет свои ограничения и не является идеальным решением.
Выше приведено подробное объяснение кода параметров переменной длины в Java, я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на этот сайт:
Подробное объяснение неявных параметров и экземпляров параметров отображения на Java
Java Программирование реализации быстрого кода сортировки и оптимизации Подробное объяснение
Заполнение шифрования Java и цифровая подпись полного кода пример
Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!