Что такое параметр в java
С помощью параметров мы можем передать в методы различные данные, которые будут использоваться для вычислений. Например:
static void sum(int x, int y)
Данная функция принимает два параметра — два числа, складывает их и выводит их сумму на консоль.
А при вызове этого метода в программе нам необходимо передать на место параметров значения, которые соответствуют типу параметра:
public class Program < public static void main (String args[])< int a = 6; int b = 8; sum(a, b); // 14 sum(3, a); // 9 sum(5, 23); // 28 >static void sum(int x, int y) < int z = x + y; System.out.println(z); >>
Поскольку метод sum принимает два значения типа int, то на место параметров надо передать два значения типа int. Это могут быть и числовые литералы, и переменные типов данных, которые представляют тип int или могут быть автоматически преобразованы в тип int. Значения, которые передаются на место параметров, еще называются аргументами . Значения передаются параметрам по позиции, то есть первый аргумент первому параметру, второй аргумент — второму параметру и так далее.
Рассмотрим другой пример:
public class Program < public static void main (String args[])< display("Tom", 34); display("Bob", 28); display("Sam", 23); >static void display(String name, int age) < System.out.println(name); System.out.println(age); >>
Метод display принимает два параметра. Первый параметр представляет тип String, а второй — тип int. Поэтому при вызове метода вначале в него надо передать строку, а затем число.
Параметры переменной длины
Метод может принимать параметры переменной длины одного типа. Например, нам надо передать в метод набор числел и вычислить их сумму, но мы точно не знаем, сколько именно чисел будет передано — 3, 4, 5 или больше. Параметры переменной длины позволяют решить эту задачу:
public class Program < public static void main (String args[])< sum(1, 2, 3); // 6 sum(1, 2, 3, 4, 5); // 15 sum(); // 0 >static void sum(int . nums) < int result =0; for(int n: nums) result += n; System.out.println(result); >>
Троеточие перед названием параметра int . nums указывает на то, что он будет необязательным и будет представлять массив. Мы можем передать в метод sum одно число, несколько чисел, а можем вообще не передавать никаких параметров. Причем, если мы хотим передать несколько параметров, то необязательный параметр должен указываться в конце:
public static void main(String[] args) < sum("Welcome!", 20,10); sum("Hello World!"); >static void sum(String message, int . nums)
Параметры методов — Основы Java
Методы могут не только возвращать значения, но и принимать их в виде параметров. С параметрами методов мы уже сталкивались много раз:
// Принимает на вход один параметр любого типа System.out.println("я параметр"); // Принимает на вход индекс, по которому извлекается символ "какой-то текст".charAt(3); // 'о' // Принимает на вход два строковых параметра // Первый — что ищем, второй — на что меняем "google".replace("go", "mo"); // "moogle" // Принимает на вход два числовых параметра // первый — начальный индекс включительно, второй — конечный индекс не включительно "hexlet".substring(1, 3); // "ex"
В этом уроке мы научимся создавать методы, которые принимают на вход параметры.
Представим, что перед нами стоит задача — реализовать статический метод App.getLastChar() . Он должен возвращать последний символ в строке, переданной на вход как параметр.
Вот как будет выглядеть использование этого метода:
// Передача параметров напрямую без переменных App.getLastChar("Hexlet"); // 't' App.getLastChar("Goo"); // 'o' // Передача параметров через переменные var name1 = "Hexlet"; App.getLastChar(name1); // 't' var name2 = "Goo"; App.getLastChar(name2); // 'o'
Из описания и примеров кода мы можем сделать следующие выводы:
- Нам нужно определить статический метод getLastChar() в классе App
- Метод должен принимать на вход один параметр типа String
- Метод должен возвращать значение типа char
Для начала определим метод:
class App public static char getLastChar(String str) // Вычисляем индекс последнего символа как длина строки минус 1 return str.charAt(str.length() - 1); > >
Разберем этот код подробнее. char говорит нам о типе возвращаемого значения. Далее в скобках указывается тип параметра String и его имя str .
Внутри метода мы не знаем, с каким конкретно значением идет работа, поэтому параметры всегда описываются как переменные.
Имя параметра может быть любым — оно не связано с тем, как вызывается метод. Главное, чтобы это имя отражало смысл того значения, которое содержится внутри. Конкретное значение параметра будет зависеть от вызова этого метода.
Параметры в Java всегда обязательны. Если методу нужны параметры, а мы попробуем написать код без параметра, то компилятор выдаст ошибку:
(); // такой код не имеет смысла method getLastChar in class App cannot be applied to given types; required: String found: no arguments reason: actual and formal argument lists differ in length
Точно таким же образом можно указывать два и более параметра. Каждый параметр отделяется запятой:
class App // Метод по нахождению среднего числа // Возвращаемый тип — double, потому что // при делении может получиться дробное число public static double average(int x, int y) return (x + y) / 2.0; > > App.average(1, 5); // 3.0 App.average(1, 2); // 1.5
Методы могут требовать на вход любое количество параметров, которое им нужно для работы:
// первый параметр – что ищем // второй параметр – на что меняем "google".replace("go", "mo"); // moogle
Для создания таких методов нужно в определении указать нужное количество параметров через запятую, дав им понятные имена. Ниже пример определения метода replace() , который заменяет в слове одну часть строки на другую:
class App public static String replace(String text, String from, String to) // здесь тело метода, но мы его // опускаем, чтобы не отвлекаться > > App.replace("google", "go", "mo"); // moogle
Когда параметров два и более, то практически для всех методов становится важен порядок передачи этих параметров. Если его поменять, то метод отработает по-другому:
// ничего не заменилось, // так как внутри google нет mo App.replace("google", "mo", "go"); // google
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Об обучении на Хекслете
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар « Как самостоятельно учиться »
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Использование необязательных параметров в Java
Одной из типичных проблем, с которыми сталкиваются разработчики, является необходимость использования необязательных параметров в Java. В других языках программирования, таких как Python или JavaScript, есть возможность установки значений по умолчанию для параметров, что позволяет их делать необязательными. В Java же такой возможности нет.
Предположим, есть функция, которая принимает три параметра.
public void exampleFunction(int param1, int param2, int param3) < // код функции >
Однако, в определенных случаях, третий параметр может быть необязательным. Как быть в таких ситуациях?
Перегрузка методов
Один из способов — это перегрузка методов. Можно создать второй метод с тем же именем, но меньшим количеством параметров.
public void exampleFunction(int param1, int param2) < exampleFunction(param1, param2, 0); // 0 - значение по умолчанию >
Таким образом, при вызове exampleFunction(param1, param2) , будет вызываться метод с двумя параметрами, который в свою очередь вызывает исходный метод exampleFunction(param1, param2, param3) с параметром по умолчанию.
Использование паттерна «Строитель»
Еще один способ — это использование паттерна «Строитель» (Builder). Этот паттерн позволяет создавать различные варианты объекта, избегая перегрузки конструктора.
public class Example < private int param1; private int param2; private int param3; public static class Builder < private int param1; private int param2 = 0; // значение по умолчанию public Builder(int param1) < this.param1 = param1; >public Builder param2(int param2) < this.param2 = param2; return this; >public Example build() < Example example = new Example(); example.param1 = this.param1; example.param2 = this.param2; return example; >> private Example() <> >
Использование объекта будет выглядеть следующим образом: Example example = new Example.Builder(1).param2(2).build();
Использование Varargs
Еще одним вариантом является использование varargs. Это позволяет принимать любое количество аргументов одного типа. Однако, это должно быть последним параметром в списке.
public void exampleFunction(int param1, int param2, int. param3) < int value = (param3.length > 0) ? param3[0] : 0; // 0 - значение по умолчанию >
Таким образом, можно вызвать exampleFunction(param1, param2) или exampleFunction(param1, param2, param3) .
Вывод
Java не поддерживает необязательные параметры напрямую, как это делают некоторые другие языки программирования. Однако, существуют различные способы обхода этой проблемы, включая перегрузку методов, использование паттерна «Строитель» и использование varargs.
Java: передача параметров по значению или по ссылке
Простое объяснение принципов передачи параметров в Java.
Многие программисты часто путают, какие параметры в Java передаются по значению, а какие по ссылке. Давайте визуализируем этот процесс, и тогда вы увидите насколько все просто.
Данные передаются между методами через параметры. Есть два способа передачи параметров:
- Передача по значению (by value). Значения фактических параметров копируются. Вызываемый метод создает свою копию значений аргументов и затем ее использует. Поскольку работа ведется с копией, на исходный параметр это никак не влияет.
- Передача по ссылке (by reference). Параметры передаются как ссылка (адрес) на исходную переменную. Вызываемый метод не создает свою копию, а ссылается на исходное значение. Следовательно, изменения, сделанные в вызываемом методе, также будут отражены в исходном значении.
В Java переменные хранятся следующим образом:
- Локальные переменные, такие как примитивы и ссылки на объекты, создаются в стеке.
- Объекты — в куче (heap).
Теперь вернемся к основному вопросу: переменные передаются по значению или по ссылке?
Java всегда передает параметры по значению
Чтобы разобраться с этим, давайте посмотрим на пример.
Поскольку Java передает параметры по значению, метод processData работает с копией данных. Следовательно, в исходных данных (в методе main ) не произошло никаких изменений.
Теперь рассмотрим другой пример:
Что здесь происходит? Если Java передает параметры по значению, то почему был изменен исходный список? Похоже, что Java все-таки передает параметры не по значению? Нет, неправильно. Повторяйте за мной: «Java всегда передает параметры по значению».
Чтобы с этим разобраться, давайте посмотрим на следующую диаграмму.
В программе, приведенной выше, список fruits передается методу processData . Переменная fruitRef — это копия параметра fruit . И fruits и fruitsRef размещаются в стеке. Это две разные ссылки. Но самое интересное заключается в том, что они указывают на один и тот же объект в куче. То есть, любое изменение, которое вы вносите с помощью любой из этих ссылок, влияет на объект.
Давайте посмотрим на еще один пример:
В этом случае для изменения ссылки fruitRef мы использовали оператор new . Теперь fruitRef указывает на новый объект, и, следовательно, любые изменения, которые вы вносите в него, не повлияют на исходный объект списка фруктов.
Итак, Java всегда передает параметры по значению. Однако мы должны быть осторожны при передаче ссылок на объекты.
Вышеприведенная концепция очень важна для правильного решения ваших задач.
Например, рассмотрим удаление узла в односвязном списке.
class Node < int data; Node next; Node(int d)< data = d; next = null; >> class LinkedList < public static Node push(Node head, int data) < Node newNode = new Node(data); newNode.next = head; head = newNode; return head; >public static void deleteNode(Node head, int position) < // List is empty if (head == null)< return; >// If position is 1st, removing head node if (position == 1) < head = head.next; return; >Node prevNode = head; int i = 2; while (prevNode != null && i != position) < prevNode = prevNode.next; i++; >// When position is more than number of node if (prevNode == null || prevNode.next == null) < return; >prevNode.next = prevNode.next.next; > public static void printList(Node head) < Node currNode = head; while (currNode != null) < System.out.print(currNode.data + " "); currNode = currNode.next; >> public static void main(String[] args) < Node head = null; head = push(head, 5); head = push(head, 4); head = push(head, 3); head = push(head, 2); head = push(head, 1); System.out.println("Created Linked list is: "); printList(head); // Delete node at position 2 deleteNode(head, 2); System.out.println("\nLinked List after Deletion at position 2: "); printList(head); >>
Это решение работает во всех случаях, кроме одного — когда вы удаляете первый узел ( Position = 1 ). Основываясь на ранее описанной концепции, видите ли вы в чем здесь проблема? Возможно, поможет следующая диаграмма.
Для исправления алгоритма необходимо сделать следующее:
public static Node deleteNode(Node head, int position) < // List is empty if (head == null)< return head; >// If position is 1st, removing head node if (position == 1) < head = head.next; return head; >Node prevNode = head; int i = 2; while (prevNode != null && i != position) < prevNode = prevNode.next; i++; >// When position is more than number of node if (prevNode == null || prevNode.next == null) < return head; >prevNode.next = prevNode.next.next; return head; > public static void main(String[] args) < Node head = null; head = push(head, 5); head = push(head, 4); head = push(head, 3); head = push(head, 2); head = push(head, 1); System.out.println("Created Linked list is: "); printList(head); // Delete node at position 2 head = deleteNode(head, 2); System.out.println("\nLinked List after Deletion at position 2: "); printList(head); >//Rest of the code remains same
В этой статье мы обсудили одну небольшую, но важную концепцию Java: передачу параметров.
Перевод статьи подготовлен в преддверии старта курса «Подготовка к сертификации Oracle Java Programmer (OCAJP)».
Подробнее о курсе и программе обучения можно узнать на бесплатном вебинаре, который пройдет 15 апреля.
ЗАПИСАТЬСЯ НА ВЕБИНАР
- Блог компании OTUS
- Программирование
- Java