Functional interface implementations should use lambda expressions (kotlin: S6516)

  • Operating system: Windows 11 64bits
  • IDE name and flavor/env:
    Android Studio Meerkat Feature Drop | 2024.3.2
    Build #AI-243.25659.59.2432.13423653, built on April 29, 2025
    Runtime version: 21.0.6±13368085-b895.109 amd64
    VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
    Toolkit: sun.awt.windows.WToolkit
    Windows 11.0
    GC: G1 Young Generation, G1 Concurrent GC, G1 Old Generation
    Memory: 8192M
    Cores: 32
    Registry:
    ide.instant.shutdown=false
    ide.experimental.ui=true
    terminal.new.ui=true
    Non-Bundled Plugins:
    com.intellij.marketplace (243.25659.59)
    com.genymotion.idea (2.0.3)
    com.knziha.vectorpathtweaker (1.9.1)
    Key Promoter X (2024.2.2)
    com.intellij.plugins.vscodekeymap (243.21565.122)
    com.vscode.jetbrainssync (1.0.18)
    com.dsoftware.ghtoolbar (2025.1.2)
    com.zanon.android.adb.adb-plugin (1.4.1)
    com.az4mxl.plugin.import-image (1.0.1)
    me.uyt.build.variant.selector (1.0.13)
    com.mistamek.drawablepreview.drawable-preview (1.1.6)
    com.intellij.settingsSync (243.25659.39)
    org.sonarlint.idea (10.23.0.81344)
GsonBuilder().registerTypeAdapter(PlayIntegrityCheck::class.java, object : JsonSerializer<PlayIntegrityCheck> {
			override fun serialize(src: PlayIntegrityCheck, type: Type, context: JsonSerializationContext): JsonElement {
				return JsonObject().apply {
					//...
				}
			}
		})

With this code, I am getting this suggestion: Functional interface implementations should use lambda expressions kotlin:S6516

But when I apply the recommendation, the app crashes with IllegalArgumentException.

Since this recommendation does not work well with Gson and Kotlin, you need to take this in consideration.

Thanks.

Hello @ATTATRA,

Welcome to the community!

Thanks for reporting this issue. I tried to reproduce it quickly, but I don’t see any runtime issue replacing anonymous class with lambda with some dummy implementation. So I think there’s not enough information in your code snippet. Could you, please, share a complete reproducer that includes this:

  • self-contained code snippet that raises an exception (probably the content of “.apply {}” is important)
  • the implementation of PlayIntegrityCheck class
  • all the imports
  • the Gson library version
  • Kotlin version
  • exception with message and stacktrace

Otherwise I can’t really investigate if there’s a problem in the rule and how to fix it.

Best,
Margarita

I have created a repository with issue for you to test: GitHub - dzboot02/S6516_issue_test

It is an Android Studio project, MainActivity is the entry point.

Stacktrace:

11:02:37.461 AndroidRuntime E FATAL EXCEPTION: main (Ask Gemini)
Process: com.example.s6516_test, PID: 5600
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.s6516_test/com.example.s6516_test.MainActivity}: java.lang.IllegalArgumentException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4164)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.IllegalArgumentException
at com.google.gson.internal.GsonPreconditions.checkArgument(GsonPreconditions.java:55)
at com.google.gson.GsonBuilder.registerTypeAdapter(GsonBuilder.java:707)
at com.example.s6516_test.Test.failing(Test.kt:27)
at com.example.s6516_test.MainActivity.onCreate(MainActivity.kt:15)
at android.app.Activity.performCreate(Activity.java:8975)
at android.app.Activity.performCreate(Activity.java:8944)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

Thanks for the reproducer.

I was able to reproduce the issue. This is happening due to such validations in the GsonBuilder:

GsonPreconditions.checkArgument(
        typeAdapter instanceof JsonSerializer<?>
            || typeAdapter instanceof JsonDeserializer<?>
            || typeAdapter instanceof InstanceCreator<?>
            || typeAdapter instanceof TypeAdapter<?>);

I will think what we can do about it, as technically according to the language this is possible, but it fails in runtime as lambda can’t pass this check. It’s type is Function3 and it can’t be cast to the JsonSerializer.

For the experiment I also tried with Java:

String failing() {
        return new GsonBuilder()
                //Works fine
                .registerTypeAdapter(Test2.class, (JsonSerializer<Test2>) (src, typeOfSrc, context) -> {
                    var jsonObject = new JsonObject();
                    jsonObject.add("field", context.serialize(src.field1));
                    return jsonObject;
                })
                .create().toJson(this);
    }

It works with Lambdas, but I had to explicitly cast it to JsonSerializer.

Unfortunately we can’t know in the general case if the function will work fine with lambda and won’t fail in runtime (don’t access type, fields, etc…).

I’ll see what we can do in this case. One of the ideas is that we limit the check to the java interfaces having @FunctionalInterface annotation. However, as it’s not mandatory, we might report in much fewer cases that we could.

Anyway, I created a ticket for this issue, so we can think of the possible solution. Meanwhile, I suggest you mark this issue as an FP.

Best,
Margarita

Got it, thanks a lot.