Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сигнатура функций в Java
Сигнатура функции — это набор характеристик метода, который однозначно определяет его в классе. Сигнатура включает имя метода и список типов параметров (в Java стандарт Java Language Specification строго определяет, что входит в сигнатуру).
Компоненты сигнатуры
Полная сигнатура функции состоит из:
Имя_метода(Тип_параметра1, Тип_параметра2, ...)
Примеры:
public class Calculator {
// Сигнатура: add(int, int)
public int add(int a, int b) {
return a + b;
}
// Сигнатура: add(double, double)
public double add(double a, double b) {
return a + b;
}
// Сигнатура: calculate(String, int, boolean)
public String calculate(String operation, int value, boolean isActive) {
return operation + value;
}
}
Что входит и не входит в сигнатуру
ВходИТ в сигнатуру:
- Имя метода
- Список типов параметров (порядок важен)
- Количество параметров
НЕ входит в сигнатуру:
- Тип возвращаемого значения
- Модификаторы доступа (public, private, protected)
- Ключевое слово static
- Выбрасываемые исключения (throws)
- Аннотации
public class Example {
// Это РАЗНЫЕ методы (разные сигнатуры)
public int getValue() { return 1; }
public String getValue() { return "1"; } // Ошибка компиляции!
// Это НЕ разные сигнатуры - это одна и та же сигнатура
// public int getAge() { return 10; }
// private int getAge() { return 10; } // Ошибка компиляции!
}
Перегрузка методов (Method Overloading)
Перегрузка позволяет иметь несколько методов с одинаковым именем, но разными сигнатурами:
public class Printer {
// Сигнатура: print(String)
public void print(String text) {
System.out.println("String: " + text);
}
// Сигнатура: print(int)
public void print(int number) {
System.out.println("Int: " + number);
}
// Сигнатура: print(double)
public void print(double number) {
System.out.println("Double: " + number);
}
// Сигнатура: print(String, int)
public void print(String text, int count) {
for (int i = 0; i < count; i++) {
System.out.println(text);
}
}
// Сигнатура: print(int, String)
public void print(int count, String text) {
for (int i = 0; i < count; i++) {
System.out.println(text);
}
}
}
// Использование
Printer printer = new Printer();
printer.print("Hello"); // print(String)
printer.print(42); // print(int)
printer.print(3.14); // print(double)
printer.print("Hi", 3); // print(String, int)
printer.print(5, "Bye"); // print(int, String)
Правила перегрузки
Методы перегружаются на основе:
- Количества параметров
- Типов параметров
- Порядка типов параметров
public class Service {
// Правильные перегрузки:
public void process(int x) { }
public void process(int x, int y) { } // Другое количество
public void process(String s) { } // Другой тип
public void process(int x, String s) { } // Другой порядок
public void process(String s, int x) { } // Другой порядок
}
Разрешение перегрузки (Method Resolution)
Компилятор выбирает метод на основе типов аргументов в момент компиляции:
public class Resolver {
public void method(Number num) {
System.out.println("Number");
}
public void method(Integer num) {
System.out.println("Integer");
}
}
Resolver resolver = new Resolver();
Integer i = 5;
Number n = 5;
resolver.method(i); // Вызовет method(Integer) - выбирается наиболее специфичный
resolver.method(n); // Вызовет method(Number)
Переопределение методов (Method Overriding)
Это ОТЛИЧАЕТСЯ от перегрузки. Переопределение происходит в наследовании:
public class Animal {
// Сигнатура: speak()
public void speak() {
System.out.println("Some sound");
}
}
public class Dog extends Animal {
// ПЕРЕОПРЕДЕЛЕНИЕ - ОДНА И ТА ЖЕ сигнатура speak()
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
// Использование
Animal dog = new Dog();
Animal cat = new Cat();
dog.speak(); // Woof! - вызывается Dog.speak()
cat.speak(); // Meow! - вызывается Cat.speak()
Подпись метода при рефлексии
В Java рефлексии сигнатура используется для поиска методов:
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) throws NoSuchMethodException {
Class<?> clazz = String.class;
// Получение метода по сигнатуре
Method method = clazz.getMethod("substring", int.class);
System.out.println(method); // public java.lang.String java.lang.String.substring(int)
// Получение метода с несколькими параметрами
Method method2 = clazz.getMethod("substring", int.class, int.class);
System.out.println(method2); // public java.lang.String java.lang.String.substring(int,int)
// Все методы класса
for (Method m : clazz.getMethods()) {
System.out.println(m.getName() + ": " + m.getParameterCount() + " params");
}
}
}
Varargs (Переменное количество аргументов)
Варарги — это способ указать переменное количество параметров одного типа:
public class VarArgsExample {
// Сигнатура: sum(int[])
public static int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
// Сигнатура: format(String, Object[])
public static String format(String pattern, Object... args) {
return String.format(pattern, args);
}
}
// Использование
VarArgsExample.sum(1, 2, 3); // sum(1, 2, 3)
VarArgsExample.sum(1, 2, 3, 4, 5); // sum(1, 2, 3, 4, 5)
VarArgsExample.sum(); // sum() - пустой массив
VarArgsExample.format("%s %d", "Hello", 42);
Важные моменты
1. Сигнатура для расширения типов:
public class TypePromotion {
public void method(int x) { System.out.println("int"); }
public void method(long x) { System.out.println("long"); }
public static void main(String[] args) {
TypePromotion tp = new TypePromotion();
tp.method(5); // Вызовет method(int)
tp.method(5L); // Вызовет method(long)
}
}
2. Сигнатура и интерфейсы:
public interface Calculator {
int calculate(int a, int b); // Сигнатура: calculate(int, int)
}
public class AddCalculator implements Calculator {
@Override
public int calculate(int a, int b) { // Одна и та же сигнатура
return a + b;
}
}
Понимание сигнатур критически важно для написания правильного Java кода, особенно при работе с перегрузкой методов, наследованием и рефлексией.