Передается ли Proxy-объект в качестве аргумента метода целевого объекта?

«Передается ли Proxy-объект в качестве аргумента метода целевого объекта?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, прокси-объект не передается в метод целевого объекта в качестве аргумента.

Что происходит на самом деле: При вызове метода на прокси-объекте управление передается в метод invoke его InvocationHandler. Этот метод получает три параметра:

  1. proxyссылка на сам прокси-объект (не передается в целевой метод).
  2. method – объект java.lang.reflect.Method, представляющий вызванный метод.
  3. args – массив аргументов, переданных в метод прокси.

Пример для ясности:

import java.lang.reflect.*;

interface Calculator {
    int add(int a, int b);
}

class CalculatorImpl implements Calculator {
    public int add(int a, int b) {
        // Этот метод НЕ получает proxy-объект в качестве параметра.
        // Он получает только int a и int b.
        return a + b;
    }
}

public class Demo {
    public static void main(String[] args) {
        Calculator target = new CalculatorImpl();

        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 1. 'proxy' — это ссылка на созданный прокси. Он доступен здесь.
                System.out.println("Proxy object: " + proxy.getClass());
                // 2. Вызов метода НА ЦЕЛЕВОМ ОБЪЕКТЕ (target).
                // Метод target.add() вызывается с аргументами из args (a, b).
                // Прокси (proxy) ему НЕ передается.
                Object result = method.invoke(target, args);
                return result;
            }
        };

        Calculator proxy = (Calculator) Proxy.newProxyInstance(
                Calculator.class.getClassLoader(),
                new Class[]{Calculator.class},
                handler
        );

        int sum = proxy.add(5, 3); // Вызов идет через handler.invoke()
        System.out.println("Result: " + sum); // Result: 8
    }
}

Ключевой момент: Прокси — это обертка. Целевой объект работает со своими исходными параметрами, не зная о существовании прокси.