@StaticObjectAdapter

Generate a static object adapter with one functional-interface slot per method.

@StaticObjectAdapter generates an adapter class for an interface. For each method on the interface, the processor also generates a functional interface; the adapter exposes a setter that lets you install a lambda for that method. Methods that have not been overridden delegate to the wrapped instance.

Usage

import com.svenruppert.proxybuilder.proxy.generated.annotations.StaticObjectAdapter;

@StaticObjectAdapter
public interface Service {
  String work(String input);
}

After compilation, you can:

ServiceStaticObjectAdapter adapter = new ServiceStaticObjectAdapter()
    .withService(new ServiceImpl())
    .withServiceMethodWorkString(input -> "adapted " + input);

adapter.work("hello");   // returns "adapted hello"

withService(...) installs the original instance. withServiceMethodWorkString(...) installs a lambda that replaces just the work(String) method. Other methods on Service continue to delegate to the original.

Why use it

This is a typed, compile-checked version of “anonymous inner class to override one method”. You get:

  • A real class name in stack traces.
  • A typed lambda slot — the compiler refuses an installer that does not match the method signature.
  • No reflection. The setter stores a FunctionalInterface reference; the generated work(...) checks whether one is installed and calls it, otherwise falls through to the original.

When to reach for it

  • You need to stub or override a few methods of a many-method interface without writing a full subclass.
  • You want to compose adapters in tests by stacking with…() calls.
  • You want this without reaching for Mockito or another reflection-heavy framework.

When not to use it

  • You want to replace every method. Just write an implementation class.
  • You want runtime configurability through a builder API. See @DynamicObjectAdapterBuilder.

Edit this page on GitHub ↗