articles
15 уровень

Методы в Java

Статья из группы Архив info.javarush
участников
Методы в Java - 1В Java приложение состоит из классов. Классы, в свою очередь, состоят из переменных. Они отвечают за хранение данных и методов, которые отвечают за поведение класса: иначе говоря, логику, которую он может предоставлять (например, обработку некоторых данных, вызов других методов, и т. д.). Говорить о таких составляющих как переменные можно долго, но мы сегодня не для этого собрались. Давайте лучше поговорим о такой составляющей класса как метод. Методы в Java - 2Метод — это именованный блок кода, объявляемый внутри класса. Он содержит некоторую законченную последовательность действий (инструкций), направленных на решение отдельной задачи, который можно многократно использовать. Иными словами, метод — это некоторая функция: что-то, что умеет делать ваш класс. В других языках тоже присутствуют функции. Только в Java они являются членами классов и, согласно терминологии ООП, называются методами. Но прежде чем продолжить, давайте рассмотрим небольшой пример:
public String constructHelloSentence(String name) {
  String resultSentence = "Hello world! My name is " + name;
  System.out.println(resultSentence);
  return resultSentence;
}
Тут ничего сложного: метод Java, задача которого сформировать строку приветствия, с именем, которое мы ему передаем. Как например — Hello world! My name is Bobby Давайте как следует разберемся с построением метода, рассмотрев каждое ключевое слово в объявлении метода (слева направо). Наше первое ключевое слово — public, и оно обозначает модификатор доступа:

Модификаторы доступа

Указывают допустимую область видимости для членов класса, то есть ограничение мест, в которых разрешается использовать какую-то переменную или метод. Методы в Java - 3В языке Java применяют такие модификаторы доступа:
  • public: публичный. Методы или поля с этим модификатором общедоступны, видимы другим классам (а точнее, их методам и полям) из текущего пакета и из внешних пакетов. Это самый широкий уровень доступа из известных;

  • protected: к методам или переменным с этим модификатором есть доступ из любого места в текущем классе или пакете, или в классах, наследующих данный, а заодно — и методы или поля, даже если они находятся в других пакетах

    protected String constructHelloSentence(String name) {...}
  • Модификатор по умолчанию. Если у поля или метода класса нет модификатора, применяется модификатор по умолчанию. В таком случае поля или методы видны всем классам в текущем пакете (как protected, только с отсутствием видимости при наследовании).

    String constructHelloSentence(String name) {...}
  • private: антипод модификатора public. Метод или переменная с таким модификатором доступны исключительно в классе, в котором они объявлены.

    private String constructHelloSentence(String name) {...}
Далее мы имеем String в сигнатуре метода (первая строка метода, описывающая его свойства).

Возвращаемое значение

Возвращаемое значение — это данные (некий результат выполнения метода), которые приходят на его место после вызова. Каждый метод имеет возвращаемое значение. Или нет?

Методы с возвращаемым значением

Это значение может быть данными любого вида: как переменной простого типа, так и ссылочного. В рассматриваемом примере мы указываем, что метод должен вернуть объект типа String, что как мы помним, является классом, описывающим строку. Второй момент здесь — слово return. Оно имеет прямое отношение к возвращаемому значению: значение, стоящее после него, будет отправлено назад, на место вызова метода, а сам же метод после return закроется. Это слово обычно идёт в последней строке метода (кроме методов с различными ветвлениями типа if, else...). Если написать код в следующей строке после return:
private String constructHelloSentence(String name) {
  String resultSentence = "Hello world! My name is " + name;
  return resultSentence;
  System.out.println(resultSentence);
}
то мы получим ругательства компилятора, что не очень хорошо (компилятор ерунду не посоветует). Также нужно помнить, что тип данных после с должен совпадать с объявленным в сигнатуре метода. Подробнее о return читайте здесь.

void

Для каких служит void в Java? Не у всех методов есть возвращаемое значение. Некоторым или нечего, или не нужно ничего возвращать. Что же тогда делать? Тогда в сигнатуре метода на место возвращаемого значения мы пишем void. Как бы выглядел наш метод без возвращаемого значения?
protected void constructHelloSentence(String name) {
  String resultSentence = "Hello world! My name is " + name;
  System.out.println(resultSentence);
}
Вы наверняка заметили, что вместе с возвращаемым значением у нас исчезло слово return Так и есть, ведь наш метод и не должен ничего возвращать. Тем не менее, его можно тут поставить, но без какого-то значения, просто return; в последней строке. Это в целом бесполезно, поэтому в методах с void он необязателен. Тем не менее, его можно применять с пользой в void методах, например, при ветвлениях или циклах, когда нужно немедленно выйти из метода. Далее в объявлении метода у нас шло constructHelloSentence.

Названия методов

constructHelloSentence — название метода, отличительная особенность, по которой мы сможем отличать тот или иной метод. И, соответственно, вызывать тот или иной метод. Методы в Java - 4Названия методов должны начинаться с маленькой буквы, но и использовать верблюжий стиль (CamelCase, верблюжий регистр): т.е. каждое следующее слово в названии стоит впритык к предыдущему и пишется с большой буквы. Наименования методов должны описывать метод (лучший комментарий — правильное именование). Для этого используйте глаголы или сочетания с глаголами: getCat, delete, createCar, и так далее. В пределах одного класса имена методов должны быть уникальными (не считая перегрузки методов, о чем поговорим немного ниже). Смотрим дальше разбираемый нами метод и видим (String name)

Параметры метода

Методы могут иметь (или не иметь) определенные данные, которые будут поступать снаружи, а именно — с места, где и был вызван метод. В нашем случае мы видим, что приходит объект типа String с именем name и в дальнейшем мы используем эту переменную в нашем методе. В методе можно использовать неограниченное количество параметров, но больше 7 — не рекомендуется. Когда мы не знаем точное количество элементов, но все эти элементы нужны для одной цели и будут одного типа (например, String), используется многоточие:
public void constructHelloSentence(String...name) {
 ...
}
Обращение к каждому элементу будет такого вида: name[0] Ничего не напоминает? Верно, массив! Ничего не изменится, если мы напишем:
protected void constructHelloSentence(String[] name) {
 ...
}
Обращение к элементам также будет вида: name[1] И ещё кое что. Аргументы метода могут быть final:
public String constructHelloSentence(final String name) {
  ...
}
Это значит, что ссылка name привязана к конкретному объекту String, и переопределить её нельзя. Про работу с ссылочными переменными и их взаимодействие с зарезервированным словом final можно прочитать в материале “Ссылочные типы данных в Java”.

Вызов методов

Итак, с созданием методов разобрались, теперь давайте поговорим об их использовании. Как вызвать метод в Java? Методы в Java - 5Каждый метод в Java находится в классе. Чтобы разобраться, как устроен вызов методов в Java, возьмем класс:
public class StringConstructor {
  public String constructHelloSentence(String name) {
     String resultSentence = "Hello world! My name is " + name;
     System.out.println(resultSentence);
     return resultSentence;
  }
}
Так как у нас метод не является статическим (это отдельная тема для разговора, выходящая за рамки сегодняшней статьи), для его вызова нужно сперва создать объект, и уже у него вызвать метод:
class Application{
  public static void main(String[] args) {
     StringConstructor stringConstructor = new StringConstructor();
     stringConstructor.constructHelloSentence("Den");
  }
}
В аргументы нашего метода мы передали строку (имя), которую хотим видеть в результирующей строке, выведенной на экран:

Hello world! My name is Den
Также стоит напомнить, что методы можно переиспользовать то количество раз, сколько нам потребуется — ограничений нет.

this

Часто в коде можно увидеть ключевое слово this, как например в сеттерах:
public void setValue(Long value) {
   this.value = value;
}
И что же оно значит? this в Java — это ссылка на текущий объект данного класса. Например, если мы создали объект:
StringConstructor stringConstructor = new StringConstructor();
то this внутри объекта stringConstructor будет ссылкой на этот же объект. this используется как для ссылки на переменную объекта (как в сеттере выше), так и для вызова некоторого метода. Мы можем немного переписать наш класс:
public class StringConstructor {

  public String constructHelloSentence(String name) {
     String resultSentence = this.getSentence()  + name;
     System.out.println(resultSentence);
     return resultSentence;
  }

  private String getSentence() {
     return "Hello world! My name is ";
  }
}
Через this мы вызываем метод данного объекта, для взятия необходимой строки. Но всё же как правило для методов this почти не используется, так как и без него идёт ссылка на метод данного объекта, в основном он используется для на переменную объекта.

Перегрузка методов

Предположим нам понадобился метод, выполняющий по сути ту же самую логику, но в предложении Hello world! вместо world мы хотим вставить своё слово (строку). Но ведь у нас уже есть метод constructHelloSentence. Значит, нам нужно придумать новое название для метода, который выполняет по сути тот же функционал? Как бы не так: в этот момент на помощь нам приходит перегрузка методов. Методы в Java - 7Перегрузка методов — это использование одного и того же имени метода несколько раз при его объявлении в классе. С точки зрения синтаксиса языка, не может быть двух одинаковых имен в некотором локальном пространстве. Но при этом допускается объявление методов с одинаковыми именами но отличающимися аргументами. Иными словами, класс содержит в себе перегруженные, когда есть два и более методов с одинаковыми названиями, но различными входными данными:
public class Constructor {

  public String constructHelloSentence(String name) {
     String resultSentence = "Hello world! My name is " + name;
     System.out.println(resultSentence);
     return resultSentence;
  }

  protected String constructHelloSentence(String firstName, String secondName) {
     String resultSentence = "Hello " + firstName + "! My name is " + secondName;
     System.out.println(resultSentence);
     return resultSentence;
  }
}
Здесь мы видим, что методы не обязаны содержать одинаковый модификатор доступа (как и возвращаемый тип). Если вызывается перегруженный метод, то из нескольких объявленных методов компилятор автоматически определяет нужный по параметрам, которые указываются при вызове.
Комментарии (29)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Евген
Уровень 6
8 марта 2023, 18:17
public class StringConstructor {
  public String constructHelloSentence(String name) {
     String resultSentence = "Hello world! My name is " + name;
     System.out.println(resultSentence);
     return resultSentence;
  }
}
Так как у нас метод не является статическим (это отдельная тема для разговора, выходящая за рамки сегодняшней статьи), для его вызова нужно сперва создать объект, и уже у него вызвать метод:
class Application{
  public static void main(String[] args) {
     StringConstructor stringConstructor = new StringConstructor();
     stringConstructor.constructHelloSentence("Den");
  }
}
Как связаны между собой эти классы? Я так понимаю, что класс StringConstructor должен наследоваться от класса Application? И не нужен ли в любом классе метод main? (в StringConstructor его нет...)
Paul
Уровень 35
31 января 2023, 10:46
Мое понимание как работают возвращаемые и не возвращаемые методы. Может кому пригодится. Java - строго типизированный язык, но есть исключение: Зарезервированное имя типа var. Вот что можно сделать
var integer = 3;
var string = "Строка";
По сути в var мы можем "положить" любой тип данных. Примерно такая же история и с не возвращаемыми методами: метод
public void example () {

    }
на самом деле возвращает "пустоту", которую можно "заполнить" любым типом данных. С возвращаемыми методами ситуация аналогичная строгой типизации переменных
int integer = 3;
String string = "Строка";
Мы заранее определяем тип переменой и не можем его поменять при объявлении. Нельзя записать
int integer = "Строка";
String string = 3;
Также и в возвращаемом методе
public String example () {

        return "Строка";
    }
Если мы определил тип возвращаемой переменой, как String, то и вернуть метод должен значение типа String. Нельзя записать
public String example () {

        return 3;
    }
Компилятор выдаст ошибку. Параметры метода никак не влияют на тип возвращаемого значения.
public String example (int a, String line, char b) {

        return "Строка";
    }
Надеюсь я правильно понял и понятно объяснил.
Paul
Уровень 35
31 января 2023, 11:30
Про вызов методов. Если после модификатора доступа (public, protected и т.д.) стоит модификатор stanic, то этот метод вызывается у класса. А если после модификатора (public, protected и т.д.) не стоит модификатор stanic, то этот метод вызывается у экземпляра класса. Если метод имеет модификатор static
public static void main(String[] args) {
       String string = example("Другая строка");
       System.out.println(string);
    }

    public static String example (String line) {

        return "Строка";
    }
то, мы его вызываем просто по имени. Если у метода нет модификатора static
public class Main {
    public static void main(String[] args) {
        Main main = new Main();
        String string = main.example("Другая строка");
        System.out.println(string);
    }

    public String example (String line) {

        return "Строка";
    }
}
то сначала мы создаем экземпляр класса, в котором объявлен не статический метод (в моем случае это класс Main)
Main main = new Main();
А только потом у экземпляра класса вызываем созданный нами не статический метод example()
String string = main.example("Другая строка");
Надеюсь я понятно объяснил разницу между статическим и не статическим методом.
Paul
Уровень 35
31 января 2023, 11:57
Если метод объявлен в одном классе, а вызывается в другом, то: У не статического метода ничего не меняется
public class Main {
    public String example (String line) {

        return "Строка";
    }
}
В классе Main я создал не статический метод example () и хочу его вызвать в другом классе
public class AnotherMain{
    public void main(String[] args) {

        Main main = new Main();

        String string = main.example("Другая строка");

        System.out.println(string);
    }
}
В новом классе AnotherMain я также создал экземпляр класса Main
Main main = new Main();
И также вызвал у экземпляра класса Main, не статический метод example()
String string = main.example("Другая строка");
Статический метод вызывается немного по-другому. Т.к. статический метод принадлежит классу, то и вызывать его нужно через обращение к классу
public class Main {
    public static String example (String line) {

        return "Строка";
    }
}
В классе Main я создал статический метод example () и хочу его вызвать в другом классе
public class AnotherMain{
    public static void main(String[] args) {

        String string = Main.example("Другая строка");

        System.out.println(string);
    }
}
В новом классе AnotherMain я не создаю экземпляр класса Main, а обращаюсь к методу example() через сам класс Main
String string = Main.example("Другая строка");
Вроде всё. Если остались вопросы - не стесняйтесь спрашивать в комментариях.
Juggerout
Уровень 6
27 января 2023, 22:59
Вообще все понятно, обожаю этот сайт! Спасибо, добрые люди.
Anonymous #3210996
Уровень 27
20 декабря 2022, 22:33
Очень запутанная подача материала. Конкретики нет. Каша одним словом.
Игорь
Уровень 4
14 сентября 2022, 04:50
не давно напоролся на один метод который нам помогает парсить юзер по имени, и у человека которые его показывал название входящего параметра не как у меня, я оставил название метода его, а вот входящий параметр поставил свой и идея начала ругаться public interface UserRepository extends JpaRepository<User,Long> { User findByFirst(String firstName); "Method 'findByFirst(java.lang.String)' is never used Cannot resolve property 'first' " а так то норм public interface UserRepository extends JpaRepository<User,Long> { User findByFirstName(String firstName); почему так?
6 декабря 2023, 10:15
метод вроде нельзя так называть, JPA не понимает твой метод по названию
Sergey Tikhontsov
Уровень 15
12 февраля 2022, 20:28
Стока апичатак!
Eugene
Уровень 28
8 декабря 2021, 15:58
Не понятно про вызов методов, грустьпечаль(
helenn
Уровень 3
20 октября 2021, 18:24
Первый пример кода, строка 3: System.out.println(result Sentence) result Sentence - не должно быть слитно?
Yan Bazhenov
Уровень 2
25 июня 2022, 20:33
Так как это имя объекта, то должно быть
Konstantin Medical Interpreter в Hospital
27 сентября 2021, 05:14
Перечитал 2 раза, так и не понял как все таки вызывать метод в классе((( а если он статистический так это вообще другая статья(( вот да не задача.
Nicolae
Уровень 3
27 июля 2021, 20:13
Я проста ничего не понимаю. Все шло хорошо до этого уровня. Или у разрабов недостаточно умения объяснить или я тупой и шансов укрепить свои знания программирования в java = 0 🤷‍♂️