Hente ut metodenavn i Java: Et smart triks med SerializedLambda

Hente ut metodenavn i Java: Et smart triks med SerializedLambda

Aug 06, 2026 java method-references reflection serialization programming-tips developer-tools

Slik henter du metodenavn i Java med denne smarte trikset

Har du noen gang bygget en CSV-parser, jobbet med et ORM-verktøy, eller laget et REST-api i Java? I så fall kjenner du nok til irritasjonen: Du trenger et feltnavn som en streng, men å hardkode noe som "author" eller "getTitle" føles feil. Det er skjørt, det er feilutsatt for refaktorering, og plutselig har du en kodebase full av magiske strenger.

Men hva om du kunne skrive dette i stedet?

String author = csvContents.get(nameOf(Book::getAuthor));
String title = csvContents.get(nameOf(Book::title));

Bare send metodereferansen direkte, og Java finner ut navnet for deg. La meg vise deg hvordan dette fungerer.

Utfordringen

Java gir deg ingen innebygd måte å hente et metodenavn fra en metodereferanse. Når du skriver Book::getAuthor, får du et Function<Book, String>-objekt. Men spørsmålet "Hva er ditt faktiske metodenavn?" finner du ingen API for.

Du kanskje tenker på refleksjon?

Method[] methods = Book.class.getMethods();
String name = methods[0].getName(); // Fungerer, men hvilken?

Problemet? Du må allerede vite hvilken metode du leter etter. Det tar bort hele poenget.

SerializedLambda-trikset

Her blir det interessant. Når Java serialiserer en lambda eller metodereferanse, lagrer den ikke bare uklar bytekode. Den lager et SerializedLambda-objekt som inneholder metadata om den opprinnelige metoden – inkludert navnet.

Trikset er å avlytte serialiseringsprosessen før den fullføres, og ta vare på det SerializedLambda-objektet.

Her er kjerneimplementasjonen:

public static <T, R> String nameOf(final Getter<T, R> methodRef) {
    return toSerializedLambda(methodRef).getImplMethodName();
}

private static <T, R> SerializedLambda toSerializedLambda(final Object methodRef) {
    try {
        try (CustomObjectOutputStream stream = new CustomObjectOutputStream()) {
            stream.writeObject(methodRef);
            return (SerializedLambda) stream.interceptedObject;
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Vi lager en egen ObjectOutputStream som fanger replaceObject-kallet. Når Java prøver å serialisere metodereferansen din, sender den inn SerializedLambda – og vi tar vare på den akkurat der.

Hvorfor dette er nyttig

Denne teknikken åpner for noen smarte mønstre:

Typesikker konfigurasjon for databehandling:

// I stedet for:
dataMapper.map(book, "title", "author");

// Kan du skrive:
dataMapper.map(book, nameOf(Book::title), nameOf(Book::getAuthor));

Kompileringstid-sikkerhet for API-kall:

// Databasespørringer som refaktoreres trygt
List<Book> results = bookRepository.findBy(nameOf(Book::getAuthor), "Shakespeare");

Hvis du omdøper getAuthor()-metoden, vil kompilatoren flagge alle nameOf(Book::getAuthor)-kall som må oppdateres. Ingen mer leting etter hardkodede strenger.

Utvidelser for metoder med parametere

Grunnmønsteret fungerer fint for null-argumentmetoder, men hva med metoder som tar parametere? Da kan du utvide tilnærmingen med egne serrialiserbare funksjonelle grensesnitt:

public interface BiFunction2<T1, T2, R> extends Serializable {
    R apply(T1 t1, T2 t2);
}

public <T1, T2, R> String nameOf(final BiFunction2<T1, T2, R> methodRef) {
    return toSerializedLambda(methodRef).getImplMethodName();
}

Nå kan du håndtere metoder som BookService::findByTitleAndAuthor eller Repository::save.

Et par ting å huske på

Selv om teknikken er kraftfull, bør du tenke på dette:

  • Ytelse: Serialisering har overhead. Ikke kall nameOf() i hot loops – kall det én gang ved initialisering og cache resultatet.
  • Serialiseringskrav: Funksjonelle grensesnitt må utvide Serializable.
  • Ikke universell: Dette fungerer for metodereferanser som kan tilordnes funksjonelle grensesnitt. For vilkårlige metoder trenger du fremdeles refleksjon.

Biblioteker som gjør jobben for deg

Hvis dette føles som for mye kode å skrive selv, godt nytt: jobben er allerede gjort. Safety Mirror-biblioteket tilbyr robuste implementasjoner og utvider konseptet til også å kunne hente ut java.lang.reflect.Method-objekter direkte – full refleksjonskraft med typesikkerhet.

Oppsummert

Javas metodereferanser er kraftfulle, men de skjuler metodenavn bevisst. Noen ganger trenger du den informasjonen tilbake. SerializedLambda-trikset gir deg en ren, typesikker måte å bygge bro på – slik at du kan skrive uttrykksfull, refaktoreringsvennlig kode samtidig som du holder de magiske strengene unna.

Enten du bygger en databehandlingspipeline, en fleksibel API-klient, eller bare er lei av å lete etter "getAuthor" i kodebasen din – denne teknikken kan være akkurat det du trenger.

Read in other languages:

BG RU UZ EL CS TR RO FI SV NL PT PL HU FR IT DE ES ZH-HANS DA EN