JavaRush /Курси /Java Syntax Zero /Параметри функції в Java

Параметри функції в Java

Java Syntax Zero
Рівень 7 , Лекція 2
Відкрита

1. Передача параметрів

А тепер найцікавіше. Як ви вже, мабуть, знаєте, за методами типу System.out.println(), у методи можна передавати параметри. Що, власне кажучи, дуже сильно підвищує користь від створення та використання методів.

То як же нам оголосити метод із параметрами? Насправді це досить просто:

public static void ім'я(параметри)
{
   код методу
}

Де ім'я — це унікальне ім'я методу, а код методу — це команди, з яких складається метод. А параметри — це параметри метода, перелічені через кому. Давайте краще розпишемо цей шаблон більш детально:

public static void ім'я(тип1 ім'я1, тип2 ім'я2, тип3 ім'я3)
{    код методу
}

Приклади:

Код Пояснення
public static void print(String str)
{
}
Оголошено метод print з параметром
String str
public static void print(String str, int count)
{
}
Оголошено метод print з двома параметрами
String str
int count
public static void write(int x, int y)
{
}
Оголошено метод write з двома параметрами
int x
int y

Якщо ми не хочемо, щоб у методу були параметри, просто залишаємо круглі дужки порожніми.

Параметри — це спеціальні змінні метода. З їх допомогою у метод можна передавати різні значення під час його виклику.

Давайте, наприклад, напишемо метод, який виводить на екран рядок тексту задану кількість разів.

Як написати код для виводу рядка на екран кілька разів, ви вже знаєте. Але який саме рядок виводити? І скільки разів? Ось для цього нам параметри і потрібні.

Ось як виглядатиме код цього завдання:

Код Пояснення
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Привіт", 10);
     printLines("Бувай", 20);
   }
}


Оголосили метод printLines з параметрами:
String text, int count
Метод виводить на екран count разів рядок text





Викликаємо метод printLines з різними параметрами

Кожного разу під час виклику метода його змінним-параметрам присвоюються передані значення, і тільки після цього починають виконуватись команди всередині метода


2. Аргументи методу

Ще трохи вашої уваги хочу звернути на виклик методу з параметрами.

Ті значення, які передаються в метод, під час його виклику, прийнято називати аргументами методу.

Давайте ще раз розберемо приклад:

Код Пояснення
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Привіт", 10);
     printLines("Па-па", 20);
   }
}


Оголосили метод printLines з параметрами:
String text, int count
Метод виводить на екран count разів рядок text




Викликаємо метод printLines з параметрами
text = "Привіт"; count = 10;
text = "Па-па"; count = 20;

Коли метод printLines викликався вперше, його змінним-параметрам були присвоєні такі значення:
String text = "Привіт", int count = 10.

Коли метод printLines викликався вдруге, його змінним-параметрам були присвоєні інші значення:
String text = "Па-па", int count = 20.

Параметри методу — це саме змінні, яким присвоюються певні значення під час виклику методу. Самі ж значення "Привіт", "Па-па", 10 і 20 називаються аргументами методу.


3. Конфлікт імен змінних при виклику методу

В якості аргументів методу можна використовувати змінні. Це просто і зрозуміло, але потенційно може викликати деякі труднощі. Розглянемо той самий приклад, але винесемо аргументи в окремі змінні:

Код Пояснення
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Привіт";
     int n = 10;
     printLines(str, n);
   }
}


Оголосили метод printLines з параметрами:
String text, int count
Метод виводить на екран count разів рядок text







Викликаємо метод printLines з параметрами:
text = str;
count = n;

Поки нічого складного: у нас є змінна str, її значення присвоюється змінній text при виклику методу. У нас є змінна n, її значення присвоюється змінній count при виклику методу. Поки все зрозуміло.

А тепер давайте перейменуємо наші змінні в методі main:

Код Пояснення
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)    {
     String text = "Привіт";
     int count = 10;
     printLines(text, count);
   }
}


Оголосили метод printLines з параметрами:
String text, int count
Метод виводить на екран count разів рядок text







Викликаємо метод printLines з параметрами:
text = text;
count = count;

Зверніть увагу на дві речі

Перше: у нас є змінні з однаковими іменами в різних методах. Це різні змінні (ми їх спеціально позначили різними кольорами). Все працює так само, як і в попередньому прикладі, коли змінні в методі main називалися str і n.

Друге: при виклику методу ніякого чаклунства не відбувається. Змінним-параметрам просто присвоюються значення аргументів. Незалежно від того, це конкретні числа, рядки, змінні чи вирази.

Після перейменування змінних в методі main нічого не змінилося. Це як були різні змінні в різних методах, так і залишилися. Ніякого магічного зв'язку між змінними text та text немає.



4. Передача посилань у методи

Сподіваюся, ти зрозумів усе з попередньої лекції, тому що зараз ми знову зачепимо передачу аргументів у методи, тільки ще глибше.

Як ти вже знаєш, деякі змінні у Java не зберігають самі значення, а адресу (посилання) блоку пам'яті, де ці значення знаходяться. Наприклад, так працюють змінні-рядки або змінні-масиви.

Коли ти присвоюєш змінній-масиву іншу змінну-масив, що відбувається? Правильно. Дві змінні починають посилатися на один і той же контейнер у пам'яті:

Передача посилань у методи

А що станеться, якщо одна з цих змінних буде змінною-параметром методу?

Код Пояснення
class Solution
{
   public static void printArraySum(int[] data)
   {
     int sum = 0;
     for (int i = 0; i < data.length; i++)
       sum = sum + data[i];
     System.out.println(sum);
   }
   
   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     printArraySum(months);
   }
}


Метод printArraySum рахує суму чисел переданого масиву і виводить її на екран

Станеться те ж саме: змінна-параметр data буде містити посилання на той же контейнер, що і змінна months. Під час виклику методу просто відбудеться присвоєння data = months.

А раз обидві змінні посилаються на один і той же контейнер цілих чисел, то метод printArraySum може не просто читати значення з масиву, але й змінювати їх!

Наприклад, ми можемо написати свій власний метод, який заповнює двовимірний масив однаковими значеннями. Ось як він міг би виглядати:

Код Пояснення
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


Метод fill проходиться по всім осередкам переданого двовимірного масиву і присвоює їм значення value.








Створюємо двовимірний масив.
Заповнюємо весь масив числом 8.


5. Методи з однаковими іменами

А тепер ще раз повернемося до імен методів.

Стандарти Java вимагають, щоб усі методи всередині одного класу мали унікальні імена. Тобто неможливо оголосити в одному класі два однакових методи.

Тільки ось при порівнянні методів на однаковість враховуються не тільки імена, а й типи параметрів! Причому імена змінних-параметрів не враховуються. Приклади:

Код Пояснення
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
Ці три методи вважаються різними. Їх можна оголосити в одному класі.
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
Усі ці п’ять методів вважаються різними. Їх можна оголосити в одному класі.
void sum(int x, int y) {
}
void sum(int data, int value) {
}
Ці два методи вважаються однаковими (їх не можна оголосити в одному класі).

Чому ж одні методи вважаються різними, а інші — однаковими? І чому не враховуються імена змінних-параметрів при визначенні унікальності методу?

Навіщо взагалі потрібна унікальність? Уся справа в тому, що коли компілятор компілює вашу програму, він має точно знати, яку саме функцію/метод ви викликаєте в певному місці.

Наприклад, ви пишете System.out.println("Привіт"). Компілятор розумний, і він легко зробить висновок, що тут викликається метод println() із параметром типу String.

А якщо ви напишете System.out.println(1.0), компілятор побачить тут виклик методу println() із параметром типу double.

Компілятор стежить, щоб під час виклику методу типи аргументів і параметрів збігалися, а на ім’я аргументу не звертає жодної уваги. У Java імена змінних-параметрів ніяк не допомагають компілятору визначити викликаний метод. Тому їх і не враховують при визначенні унікальності методу.

Ім’я методу та типи його параметрів називаються сигнатурою методу. Приклад: sum(int, int)

Кожен клас має мати не методи з унікальними іменами, а методи з унікальними сигнатурами.


Коментарі (17)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Ivan Kravets Рівень 22
17 грудня 2023
остання задача геть не цікава ціла купа безглуздої писанини
Dmytrii Рівень 28
15 червня 2024
это упражнение на механическую память
ZSUnix Рівень 10
17 грудня 2024
Чому ж? Якщо підійти до цієї справи творчо, можна навіть розважитися. наприклад осьтак:
 
public class Solution {

    public static void main(String[] args) {

    }

    public static void universalMethod(){
        //1 
    }
    
    public static void universalMethod(int i1234567890987654321){
         //2                                           
    } 
    
    public static void universalMethod(byte skilbkuGodunZalushulosyaJutuHuylu){
         //3 
    }
    
    public static void universalMethod(PutinZdoh pz){
                                       
    }   //4 
    
    public static void universalMethod(String putinHuyloLaLaLaLaLaLaLaLa){
        //5                                 
    }                                    
    public static void universalMethod(long vidstanbDoNebaRachku){
        //6 
    } 
    public static void universalMethod(Dohuya naSkilkuSmatkivSvunosobakuRozruvayeFPV){
       //7 
    }
    public static void universalMethod(double adunPalkaDvaStrynaaaaYaXazyaykaVsyaStranaaaaaaaaaaa){                         
       //8  
    } 
    public static void universalMethod(float adunPalkaDvaStrynaaaa){          
       //9 
    } 
    public static void universalMethod(int[][][][][][][][][][][] matrucyaProstoryVMTeoriyi){
        //10 
    }  
    
        //напишіть тут ваш код                       
    protected class PutinZdoh{
        boolean don = false;     
        
        public boolean putinZdoh(){
            return !don;
        } 
    }    
        
    protected class Dohuya{
        long[] dohuya = new long[100500];  
    }    
}            
 
Доречі, це моє графоманство пройшо варифікацію з першого разу. тож не лінуйтеся розважати себе, і підходьте творчо до нудних завдань.
Grimnir Рівень 19
24 серпня 2025
Можна сприйняти її, щоб згадати 8 примітивів + String + без параметрів
Михайло Рівень 1 Expert
23 лютого 2023
задача про власника "Бешеної коняки топ"
Anonymous #3257141 Рівень 18
22 лютого 2023
В задачі "Правильний порядок", де потрібно було зробити реверс елементів масиву реалізував метод reverseArray через цикл for, але простіше. Результат виконання правильний, але рішення не було прийнято:( Тому прийшлося подивитися "правильне" рішення.
Олександр Рівень 18
3 листопада 2023
Я теж подивився відповідь, і тільки потім зрозумів, що в умові сказано що треба змінити порядок єлементів в масиві, а не змінити порядок виведення. В консоль по ітогу виведеться тільки два рядки, як і вказано в умові.
Гаркін Рівень 14
19 лютого 2024
Я також подивився рішення після здачи завдання. І рішення від JavaRush більш.. .елегантне. Я створював проміжний масив та два цикли for , а вони зуміли в одному циклі і без створення додаткового масиву. Треба запам'ятати собі таке рішення.
10 січня 2023
Добрый день. Кто знает помогите разобраться. При решение задачи с параметрами возникла ошибка что имя переменной уже используется: public static void universalMethod(int q); public static void universalMethod(String q); public static void universalMethod(String q,int q); После как заменив int q на int a, задачу приняли. public static void universalMethod(int q); public static void universalMethod(String q); public static void universalMethod(String q,int a); 1. Вопрос почему ошибку показало хотя это разные параметры? "Причому імена змінних-параметрів не враховуються" - так написано в уроке. 2. Если это даже считаются одинаковые параметры, почему параметр String да еще с одинаковой переменной не сработал как ошибку?
kivi Рівень 20
22 січня 2023
в третьому методі дві змінні мають однакову назву, не залежно від того чи ви їх декларували раніше (в 1 та 2 методі), у вас перший параметр це String q, тому при спробі задекларувати int q, воно вважає це за помилку, це називається "перегрузка" Згідно з документацією java: Компілятор не враховує тип повернення під час диференціювання методів, тому ви не можете оголосити два методи з однаковою сигнатурою, навіть якщо вони мають різний тип повернення. https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html
HochDev Рівень 23
27 листопада 2022
Перейменування параметрів в IntelliJ IDEA оптимально робити через пункт меню Refactor-Rename.
Tehnik Рівень 11
1 листопада 2022
Привет всем. Подскажите, в задание с reverseArray, я создал новый масив int[ ] a, циклом присвоил ему значения в обратном порядке и потом добавил строку array = a. но к методу printArray все равно передается изначальный масив. по шагово просмотре, то масив а заполняется ноaрмально и в конце метода масив array имеет адрес и значения масива а. в чем тут дело?
Roma Chernesh Рівень 16
14 грудня 2022
Можно побачити код? Бо так незрозуміло. Взагалі-то, там задача дублювання масиву не потребує, але гадаю, що можно і таким (як ви описали) чином розв'язати
Neridnyi Taras Рівень 23
21 вересня 2022
завдання medium складності у валідатор не проходить, тим часом у jdk на пк легко проходить і результат правильний ?


    public static void reverseArray(int[] array) {
        // напишіть тут ваш код
        for (int i = array.length - 1; 0 < i + 1; i--) {
            System.out.print(array[i] + " , ");
        }
        System.out.println();
    }

і Код без помилок
Andriy Рівень 16
1 жовтня 2022
в консоль виводити не потрібно, потрібно зробити зміни саме в масиві
Oleksandr Рівень 23
15 жовтня 2022
void метод нічого не повертає, яким чином тоді повернуться данні назад?
Orest Orest Рівень 10
30 липня 2022
Розпакоука, сьодні неділя, був хліб 😂🤣 це до першої задачі 😆