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
Методы Java — как вызывать и использовать
Что такое методы в Java, как они работают, когда их называют абстрактными. Учимся пользоваться готовыми методами языка, а также объявлять, определять, перегружать и вызывать собственные.
03 ноября 2017 4 минуты 269414

Автор статьи
Мария Лисянская

Автор статьи
Мария Лисянская
https://gbcdn.mrgcdn.ru/uploads/post/1283/og_cover_image/f0ecb16fc23bee81f9e830b5b2a56ae1

В объектно-ориентированном программировании метод — это именованный блок кода, который объявляется внутри класса и может быть использован многократно. Если вы знакомы с процедурным программированием (Pascal, Basic), вспомните, что такое функция — по принципу работы у неё и метода много общего.
Хорошо написанный метод решает одну практическую задачу: находит квадратный корень из числа (как штатный метод sqrt() в Java), преобразует число в строку (метод toString()), присваивает значения полям объекта и так далее.
Новый метод сначала объявляют и определяют, затем вызывают для нужного объекта или класса.
Штатные — встроенные — методы языка работают со служебными объектами. Например, метод print в Java выводит значения в консоль. Вызывают его так:
System.out.print("Привет, мир!");
Обратите внимание на структуру: у класса System есть поле out — поток ввода/вывода. Поле — тоже объект, и у него есть метод print(), который мы вызываем.
Ещё есть метод println(), который при выводе значений автоматически переводит каретку на следующую строку. Это избавляет от необходимости ставить «\n» в месте переноса строки.
Чтобы Java-приложение могло работать, в его базовом классе обязательно нужно объявить метод main.
public static void main(String[] args) < // здесь основной код и вызовы других методов >
Как видите, в качестве параметра main принимает массив строк, в данном случае — параметров запуска.
Объявление и определение метода в Java
Методы могут возвращать или не возвращать значения, могут вызываться с указанием параметров или без. Тип возвращаемых данных указывают при объявлении метода — перед его именем.
В примере ниже метод должен найти большее из двух целых чисел, поэтому тип возвращаемого значения — int:
public static int maxFinder(int a, int b) < //заголовок метода //ниже — тело метода int max; if (a b) max = b; else max = a; return max; >
В заголовке метода сначала идут модификаторы, определяющие, на каких условиях он доступен для вызова. Об этом чуть ниже. Вернёмся к заголовку: int — возвращаемый тип, maxFinder — имя метода, в скобках — параметры.
В теле метода заводим переменную max, куда потом запишем большее число. Далее сравниваем значения, фиксируем большее в max и возвращаем.
Обратите внимание, return может работать не только с одной переменной, но и с выражением. Если бы мы не сравнивали значения, а складывали, результат можно было бы вернуть без дополнительной внутренней переменной. В теле метода была бы всего одна строка:
return a+b;
Когда метод не должен ничего возвращать, тип возвращаемого значения указывают как void. А если методу для работы не нужны входные параметры, скобки оставляют пустыми:
static void theWarning() < System.out.println("Мне ничего не надо, и вы от меня ничего не получите."); >
Как вызвать метод в Java
Метод с модификатором public можно вызывать из любого класса, в том числе размещенного во внешнем файле. Если нужно, чтобы метод был доступен исключительно внутри своего класса, применяют модификатор private. Есть и более мягкий вариант ограничения доступа: методы с модификатором protected доступны подклассам своего класса и другим классам из того же пакета. Чем сложнее получить доступ к методу извне, тем безопаснее — ниже риск ошибок.
Статический метод в Java принадлежит классу, а не объектам (и экземплярам) класса. Поэтому его вызывают без создания экземпляра.
Для простоты мы сделали методы публичными и статическими и разместили их в главном классе программы.
Вызывают методы двумя способами — в зависимости от того, возвращают они что-то или нет. Если да, подставляем значение, куда нам нужно:
public static void main(String args[]) < System.out.print(maxFinder(3,8)); >
Мы вызвали maxFinder и сразу вывели результат его работы на экран. Для примера числа заданы вручную, как неименованные константы, но в реальных приложениях обычно сравнивают значения переменных.
После вызова метод управляет программой до окончания своей работы: пока в его теле не сработает оператор возврата или прерывания, либо пока не будут выполнены все находящиеся в нём инструкции.
Вызовем theWarning, который ничего не возвращает:
public static void main(String args[]) < theWarning(); System.out.print(“theWarning завершил свою работу. Идём дальшe.”); >
Этот метод обходится без помощников — делает, что должен, и передаёт управление последующему коду.
Вызов метода из другого класса
А если бы maxFinder находился в отдельном классе и был не статическим? Тогда для его вызова пришлось бы сначала создать объект класса, в котором он находится. Допустим, метод находится в классе SampleClass. Вызываем:
public void main(String args[]) < SampleClass sc= new SampleClass(); System.out.print(sc.maxFinder(5,8)); >
Статический метод вызывают через точку от имени класса — вот так:
System.out.print(SomeClass.maxFinder(5,8));
Перегрузка методов в Java
Что, если нам нужно сравнивать не только целые числа, но и числа с плавающей точкой? Реализовать это поможет перегрузка метода. Копипастим метод maxFinder в тот же класс, заменяем типы всех задействованных значений на double:
public static double maxFinder(double a, double b) < double max; //остальную часть тела метода оставляем без изменений >
Имя метода не меняем! Это и есть перегрузка: компилятор сам выберет, какую из версий метода использовать — в зависимости от того, значения какого типа сравниваем.
Ключевое слово this в методах Java
Ключевое слово this позволяет ссылаться на экземпляры класса: их переменные, методы и конструкторы. Используют this только внутри метода или конструктора экземпляра. Например, вот так можно связать входные параметры метода с одноименными параметрами конкретного экземпляра класса:
class UserData < int id, age, phone; void setProfileData(int id, int age, int phone) < this.id=id; this.age=age; this.phone=phone; > >
Ещё пример — вызов одного конструктора из другого:
class ProfileData < int id; ProfileData() < this(100); > ProfileData(int id) < this.id = id; > >
Это называется «явный вызов конструктора».
Абстрактные методы в Джаве
Абстрактным называют метод, который объявлен без реализации — он не имеет ни тела, ни даже фигурных скобок. Перед именем такого метода ставят модификатор abstract:
abstract void methodName();
Зачем он такой нужен? В качестве шаблона для других методов из других классов. Вот есть у нас абстрактный класс «Строение», а в нём — абстрактный метод «возвести». Реализовывать эти абстракции нужно через несколько неабстрактных классов-наследников и их методы. Пример: класс «Хижина» — метод «стройХижину», класс «Мост» — метод «стройМост» и др.
package ru.your.classes; abstract class Construction < abstract void build_it(String msg1); abstract void sell_it(String msg2); > public class Hut extends Construction < // неабстрактный класс @Override // переопределяем метод void build_it(String msg1) < System.out.println("Хижина построена!"); > @Override void sell_it(String msg2) < System.out.println("Хижина продана."); > > public abstract class Bridge extends Construction < @Override void build_it(String msg1) < System.out.println("Мост построен!"); > // Допустим, продавать объекты класса Bridge не предполагается. // Тогда sell_it можем не переопределять. // Но обязательно создадим абстрактный дочерний метод: abstract void sell_it(String msg2); >
Поскольку конкретной реализации у абстрактного класса нет, экземпляры его создавать нельзя. Он — шаблон, который задаёт структуру для других классов и содержит объявления методов.
Кроме этого, рекомендуем помотреть вебинар по введению в ООП на Java, где также будет рассматриваться работа с методами и конструкторами.
Java. Аргументы переменной длины в методах. Перегрузка методов с аргументами переменной длины. Свойство length. Примеры
Аргументы переменной длины в методах. Перегрузка методов с аргументами переменной длины. Свойство length . Примеры
Поиск на других ресурсах:
1. Что такое аргументы метода? Что такое параметры метода? Какое отличие между аргументами и параметрами?
Если рассматривать объявление метода, то в нем после имени метода указывается список параметров, например
return_type SomeMethod(type1 param1, type 2 param2, . typeN paramN) < // тело метода, использует параметры param1, param2, . paramN // . >
- return_type – тип, возвращаемый методом;
- SomeMethod – имя метода;
- param1 , param2 , paramN – имена параметров метода, которые имеют соответственно типы type1 , type2 , typeN . Эти имена параметров метод использует для выполнения своей работы (функции).
Если этот метод SomeMethod() вызвать из другого кода, то в него передаются аргументы, например
. // вызов метода, в метод передаются аргументы SomeMethod(arg1, arg2, . argN); .
где arg1 , arg2 , argN – аргументы, которые передаются в метод. При вызове эти аргументы неявно передаются (копируются) в параметры. Аргумент arg1 передается (копируется) в параметр param1 , аргумент arg2 передается в param2 , аргумент argN передается в paramN .
Итак, параметры – это переменные (константы), которые описываются в круглых скобках при объявлении метода. Аргументы – это переменные, константы, значения которые передаются в метод при его вызове из другого кода.
2. Что такое аргументы переменной длины в методах? Общая форма объявления метода с аргументами переменной длины
Аргументы переменной длины – это переменное количество аргументов, которые может получать метод при вызове из другого кода (другого метода). Другими словами, метод может вызываться с разным количеством аргументов. Такой метод называется методом с аргументами переменной длины.
Методы, которые поддерживают переменное количество аргументов должны соответствующим образом объявляться. Общая форма метода, получающего переменное количество аргументов следующая:
return_type MethodName(type . var) < // . // >
- return_type – тип, возвращаемый методом;
- MethodName – имя метода;
- type – тип параметров переменной длины, которые получает метод. Список параметров передается в виде массива с именем var ;
- var – имя массива со списком параметров типа type .
3. В каких случаях целесообразно применять аргументы переменной длины?
Использование аргументов переменной длины в методах дает следующие преимущества:
- упрощается программный код, так как не нужно объявлять много реализаций перегруженных методов, которые получают разное количество аргументов;
- в метод может быть передано любое количество любых аргументов заданного типа;
- в метод может быть передано произвольное количество аргументов любого типа. В этом случае метод должен принимать аргументы переменной длины типа Object . Такая передача не требует каких-то дополнительных преобразований в программе;
- не нужно предварительно формировать массив значений для передачи его в метод. Значения аргументов передаются в метод через запятую.
4. Примеры методов, которые получают переменное количество аргументов
Пример 1. Объявляется метод SumParams() , который вычисляет сумму аргументов переменной длины.
// метод, который получает аргументы переменной длины // T - массив аргументов типа int static int SumParams(int . T) < int sum = 0; for (int i=0; ilength; i++) sum += T[i]; return sum; >
Использование метода в другом программном коде
int sum; sum = SumParams(1, 3, -2, 4, 8); // sum = 14 sum = SumParams(); // sum = 0 sum = SumParams(1, 2, 3); // sum = 6
Пример 2. Метод Max() , находящий максимум между списком аргументов.
// метод, который находит максимум между списком параметров static double Max(double . D) < double max; if (D.length == 0) return 0; max = D[0]; for (int i=0; ilength; i++) if (max < D[i]) max = D[i]; return max; >
Использование метода в другом методе
double max; max = Max(3, 5, 2.8, 12.75); // max = 12.75 max = Max(4.33); // max = 4.33 max = Max(); // max = 0.0 max = Max(-1.5, -3.8, -112.23); // max = -1.5
Пример 3. Метод, который возвращает массив отсортированных параметров типа float . Параметры сортируются в порядке убывания.
static float[] ToSortArrayFloat(float . F) < float t; // вспомогательная переменная if (F.length<2) return F; // сортировка вставкой for (int i=0; i for (int j=i; j>=0; j--) if (F[j]return F; >
float[] FR; // результирующий массив FR = ToSortArrayFloat(-0.5f, 0.2f, 0.3f, -0.4f); // FR = [0.3, 0.2, -0.4, -0.5] FR = ToSortArrayFloat(1, -2, 3); // FR = [ 3.0, 1.0, -2.0 ] FR = ToSortArrayFloat(); // FR = [ ]
5. Как в методе определить количество аргументов переменной длины, переданных в него?
При передаче в метод аргументов переменной длины их количество определяется с помощью свойства length .
Например. Пусть задается метод Average()
// метод, вычисляющий среднее арифметическое списка параметров static double Average(double . list) < double avg=0; int n; // свойство length - общее количество параметров, переданных в метод n = list.length; // вычисление суммы элементов for (int i=0; i return avg/n; >
В методе, в строке
n = list.length;
вычисляется общее количество аргументов переменной длины, которые были переданы в метод.
Использование метода в другом программном коде может быть, например, следующим:
double Avg; Avg = Average(3, 5, 7, 10); // Avg = 6.25
6. Можно ли в объявлении метода объединять обычные аргументы (параметры) с аргументами переменной длины?
Да, можно. Но, при условии, что выполняются следующие правила:
- объявление аргументов (параметров) переменной длины может следовать после объявления обычных аргументов;
- аргументы переменной длины должны указываться в методе только один раз;
- не допускается смешанная очередность следования обычных аргументов с аргументами переменной длины.
7. Пример объявления и использования метода, в котором используются обычные аргументы с аргументами переменной длины
Объявление метода, который получает последовательность аргументов переменной длины и возвращает двумерный массив, сформированный из этих аргументов. Размерность результирующего массива m×n задается обычными аргументами.
Реализация метода ConvertToArray2() следующая
// метод, который превращает одномерный массив параметров // в двумерный массив заданного размера m*n static int[][] ConvertToArray2(int m, int n, int . params) < int[][] A = new int[m][n]; // результирующий массив int row, col; // обнулить массив A for (int i=0; i for (int j=0; j int len = params.length; if (len>m*n) len=m*n; // сформировать массив A for (int i=0; i // возврат массива из метода return A; >
Использование массива в другом программном коде
// тестирование метода ConvertToArray2() int[][] res; // результирующий массив int m=2, n=3; // размерность массива // последовательность конвертируется в двумерный массив размером 2*3 // лишние элементы урезаются resA = ConvertToArray2(m,n,11,12,13,21,22,23,24,25,26); // resA = < < 11, 12, 13>, < 21, 22, 23>> // вывод массива res for (int i=0; i for (int j=0; jout.print(" " + resA[i][j]); System.out.println(); >
В результате выполнения вышеприведенного фрагмента кода будет выведен следующий результат:
11 12 13 21 22 23
8. Пример объявления и использования метода с переменным количеством аргументов, которые являются экземплярами класса
Задан класс Book , реализующий книгу
// класс, описывающий книгу class Book < String title; // заголовок книги String author; // название автора int year; // год выпуска float price; // стоимость книги >
Ниже приведен метод GetMaxCostBook() , получающий переменное количество аргументов типа Book . Метод возвращает ссылку на книгу, которая имеет наибольшую стоимость.
// метод, который получает массив книг в качестве параметров // метод возвращающий книгу, которая имеет наибольшую стоимость static Book GetMaxCostBook(Book . B) < Book bk=null; // проверка if (B.length==0) return bk; // цикл вычисления книги с наибольшей стоимостью bk = B[0]; for (int i=1; ilength; i++) if (bk.priceprice) bk = B[i]; return bk; >
Демонстрация использования метода GetMaxCostBook() может быть такой:
// тестирование метода GetMaxCostBook() Book B1 = new Book(); Book B2 = new Book(); Book B3 = new Book(); Book B4 = new Book(); // формирование значений книг B1.title = "Title1"; B1.author = "Author1"; B1.price = 12.50f; B1.year = 2007; B2.title = "Title2"; B2.author = "Author2"; B2.price = 7.77f; B2.year = 2023; B3.title = "Title3"; B3.author = "Author3"; B3.price = 19.95f; B3.year = 2019; B4.title = "Title4"; B4.author = "Author4"; B4.price = 11.15f; B4.year = 2009; // вызов метода Book resBook; resBook = GetMaxCostBook(B1,B2,B3,B4); if (resBook!=null) < // вывод результата String title = resBook.title; String author = resBook.author; float price = resBook.price; int year = resBook.year; System.out.println("title color: #0000ff;">out.println("author color: #0000ff;">out.println("price color: #0000ff;">out.println("year color: #333300;">⇑9. Каким образом осуществляется перегрузка методов с аргументами переменной длины? Пример
Метод, который получает аргументы переменной длины, может иметь несколько перегруженных реализаций. Такие реализации отличаются между собой типом получаемых значений.
Пример. Объявляется класс CalcSum, содержащий три перегруженных реализации метода Sum(), который находит сумму параметров для типов int, double, float.
// класс, который содержит перегруженный метод Sum() class CalcSum < // перегруженный метод Sum для целых типов int Sum(int . params) < int sum = 0; for (int i=0; ilength; i++) sum+=params[i]; return sum; > // Sum() для типа double double Sum(double . params) < double sum = 0; for (int i=0; ilength; i++) sum+=params[i]; return sum; > // Sum() для типа float float Sum(float . params) < float sum = 0.0f; for (int i=0; ilength; i++) sum+=params[i]; return sum; > > public class VarArguments < public static void main(String[] args) < // TODO Auto-generated method stub CalcSum cs = new CalcSum(); int sumInt; double sumDouble; float sumFloat; // вызов перегруженного метода с типом int sumInt = cs.Sum(2,3,5); // вызов перегруженного метода с типом double sumDouble = cs.Sum(2.05, 1.88, -3.95, 4.4); // вызов перегруженного метода с типом float sumFloat = cs.Sum(0.8f, -0.3f, 2.5f, 2.34f); System.out.println("sumInt color: #0000ff;">out.println("sumDouble color: #0000ff;">out.println("sumFloat color: #0000ff;">main() на экран будет выведен следующий результатsumInt = 10 sumDouble = 4.38 sumFloat = 5.3410. В чем состоит суть ошибки «неоднозначности» при использовании аргументов переменной длины?
Ошибка неоднозначности может возникнуть в случае, если для вызова подходят две и больше реализации перегруженного метода. В этом случае компилятор не знает, какой из перегруженных методов вызвать.
Например. Пусть заданы перегруженные методы с именем Method()
static void Method(int . params) < // . > static void Method(boolean . params) < // . >Method(); // ошибка неоднозначностикомпилятор не будет знать, какой перегруженный вариант метода Method() нужно вызвать.
Это касается комбинации существующих простых типов с типом boolean . Если объявить два перегруженных метода с типами int и double , то этой ошибки не произойдет.
11. Как сделать, чтобы метод принимал любое количество аргументов любого типа? Пример
В этом случае объявляется метод с аргументами переменной длины типа Object . Как известно, в Java все классы являются производными от общего корневого класса Object . Иногда такие методы являются еффективными, в особенности, если заведомо неизвестно тип (класс) который получает метод.
Например. Объявляется класс Error и метод ShowInfo() , принимающий аргументы переменной длины типа Object . Программный код модуля, который демонстрирует использование метода, который принимает любое количество любых аргументов
// класс, описывающий некоторую возможную ошибку в некоторой программе class Error < String errorString; // название ошибки int code; // код ошибки Error(String _errorString, int _code) < errorString = _errorString; code = _code; > > public class VarArguments < // метод, который принимает аргументы переменной длины типа Object static void ShowInfo(Object . objects) < String s; // вывод информации об аргументах, переданных в метод for (Object o : objects) System.out.println(o.toString()+" "); System.out.println("----------------"); > public static void main(String[] args) < // TODO Auto-generated method stub // Демонстрация использования метода ShowInfo() // 1. Передача аргументов типа int ShowInfo(3,5,7,2); // 2. Передача аргументов типа Error Error e1 = new Error("Divide by 0", 1); Error e2 = new Error("Abnormal program termination", 2); ShowInfo(e1,e2, new Object[] < new Error("Error message", 3) >); // 3. Передача аргументов типа float ShowInfo(2.8, 3.55, -10.12, 18.13, 0.01); > >В результате выполнения функции main() будет выведен следующий результат
3 5 7 2 ---------------- Error@1db9742 Error@106d69c [Ljava.lang.Object;@52e922 ---------------- 2.8 3.55 -10.12 18.13 0.01Связанные темы
- Передача параметров в методах класса. Передача переменных примитивных типов и объектов в метод в качестве параметра
- Перегрузка методов в классах. Перегрузка конструкторов
Параметры методов — Основы 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 студентов
Наши выпускники работают в компаниях:
