Default parameters without JvmOverloads
DEFAULT_PARAMETERS_WITHOUT_JVM_OVERLOADS reports public functions and constructors that declare
default parameter values without @JvmOverloads.
| Diagnostic | DEFAULT_PARAMETERS_WITHOUT_JVM_OVERLOADS |
| Default severity | Error |
| Applies to | JVM compilations only |
| Gradle property | defaultParametersWithoutJvmOverloads |
| Exemption | @IntentionallyWithoutJvmOverloads |
What it reports
A public function or constructor that declares at least one default parameter value but carries
no @JvmOverloads.
@file:JvmName("Sockets")/** Opens a socket to [host]. */public fun openSocket(host: String,port: Int = 80,timeout: Int = 30,) { }
Rationale
Without @JvmOverloads, Java callers of a function with three defaulted parameters have to spell
out all three at every call site. See Kotlin's guide on
overloads generation
for how @JvmOverloads compiles the reduced overloads Java needs.
Don't
@file:JvmName("Connections")/** Connects to [host]. */public fun connect(host: String,port: Int = 80,timeout: Int = 30,) { }
Do
@file:JvmName("Connections")/** Connects to [host]. */@JvmOverloadspublic fun connect(host: String,port: Int = 80,timeout: Int = 30,) { }
Don't
/** A connection to [host]. */public class Connection(host: String,port: Int = 80,)
Do
/** A connection to [host]. */public class Connection @JvmOverloads constructor(host: String,port: Int = 80,)
Notes
- A defaulted parameter in the middle of the list still can't be skipped from Java even with
@JvmOverloads. Keep optional parameters last (seeREQUIRED_PARAMETER_AFTER_OPTIONAL) so the generated overloads actually cover the common call shapes. - Abstract and interface members, and annotation class constructors, are not reported:
@JvmOverloadsdoesn't apply to them. suspendfunctions and members of a value class are not reported: they are not Java-callable regardless of overloads.- Overrides are not reported: they can't re-declare default values.
@PublishedApi internaldeclarations are not reported: their public bytecode entry is a binary implementation detail, not supported Java source API.@JvmSyntheticfunctions and constructors are hidden from Java on purpose and are not reported.- Non-JVM compilations never register this check at all.
Exemption
Apply @IntentionallyWithoutJvmOverloads to the function or constructor when serving Java callers
the full signature only is intended, for example when the defaulted parameters make no sense
without Kotlin's named arguments:
@file:JvmName("Connections")// Supporting options type/** Options applied after connecting. */public class ConnectionConfig/** Connects to [host] and applies [options]. */@IntentionallyWithoutJvmOverloads(reason = ExemptionReason.IGNORE_JAVA_INTEROP,description = "Kotlin-only function. " +"Java callers are expected to use the builder instead.",)@IntentionallyKotlinOnlyApi(reason = ExemptionReason.API_DESIGN)public fun connect(host: String,port: Int = 80,timeout: Int = 30,builder: ConnectionConfig.() -> Unit,) { }
Configuration
apiWatchdog {javaInterop {defaultParametersWithoutJvmOverloads = WatchdogSeverity.WARNING}}
The property lives inside the javaInterop { } block. javaInterop { enabled = false } turns off
this check along with the rest of the Java interop checks group.
With direct compiler invocation:
-P plugin:org.jetbrains.kotlin.library.api.watchdog:diagnosticSeverity=DEFAULT_PARAMETERS_WITHOUT_JVM_OVERLOADS:warning
See also
- Overloads generation
- Java interop checks
- Required parameters after optional ones, which keeps defaulted parameters last so the generated overloads are useful
- Exemptions and internal API