Kotlin external Keyword
last modified April 19, 2025
Kotlin's external
keyword enables interoperability with native code.
It marks declarations that are implemented outside Kotlin. This tutorial explores
the external
keyword in depth with practical examples.
Basic Definitions
The external
keyword in Kotlin indicates that a declaration is
implemented in platform-specific code. It's used for JNI (Java Native Interface)
and JavaScript interoperability. The actual implementation must be provided
externally.
Basic external Function
The simplest use of external
is to declare a function implemented
in native code. The function body is omitted as it's provided externally.
package com.zetcode external fun helloFromNative() fun main() { helloFromNative() }
Here we declare an external
function without implementation. The
actual native code would be written in C/C++ and linked via JNI. The Kotlin
code can call it like any other function.
external with JNI
When working with JNI, external
marks functions implemented in C/C++.
The function names must follow JNI naming conventions for proper linking.
package com.zetcode external fun nativeAdd(a: Int, b: Int): Int fun main() { System.loadLibrary("nativeLib") val sum = nativeAdd(5, 7) println("Sum from native: $sum") }
This example shows a native function that adds two integers. The corresponding
C function would be named Java_com_zetcode_JNIFunction_nativeAdd
.
The library is loaded before calling the native function.
external Properties
Properties can also be marked as external
. The getter and setter
must be implemented in native code. This is useful for accessing native state.
package com.zetcode external var nativeCounter: Int fun main() { System.loadLibrary("nativeLib") nativeCounter = 10 println("Counter value: $nativeCounter") }
Here we declare an external
property that's backed by native code.
The native implementation must provide both getter and setter functions. The
property behaves like a regular Kotlin property.
external Class
Entire classes can be marked as external
. All members of such
classes must be external
as well. This is common for JNI wrappers.
package com.zetcode external class NativeMath { fun add(a: Int, b: Int): Int fun subtract(a: Int, b: Int): Int } fun main() { System.loadLibrary("nativeLib") val math = NativeMath() println("5 + 3 = ${math.add(5, 3)}") println("5 - 3 = ${math.subtract(5, 3)}") }
This external
class declares methods implemented in native code. The
native implementation must provide all declared methods. The class can be used
like any regular Kotlin class.
JavaScript Interop
When targeting JavaScript, external
is used to access JavaScript
APIs from Kotlin code. The declarations map directly to JavaScript objects.
package com.zetcode external fun alert(message: String) external val document: dynamic fun main() { alert("Hello from Kotlin/JS!") document.getElementById("demo").innerHTML = "Updated" }
In Kotlin/JS, external
declarations map to JavaScript APIs. Here we
declare the alert
function and document
object. The
dynamic
type allows flexible access to JavaScript properties.
external Companion Object
Companion objects can be marked as external
to provide native
implementations for static methods. This is useful for utility functions.
package com.zetcode class NativeUtils { companion object { external fun getSystemTime(): Long } } fun main() { System.loadLibrary("nativeLib") val time = NativeUtils.getSystemTime() println("System time: $time") }
This example shows an external
companion object function. The native
implementation would be a static JNI function. The function is called through
the companion object like a static method.
external with Platform Libraries
The external
keyword can be used with platform-specific libraries.
This example demonstrates accessing a Windows API function.
package com.zetcode external fun MessageBoxA( hWnd: Int, text: String, caption: String, uType: Int ): Int fun main() { System.loadLibrary("user32") MessageBoxA(0, "Hello from Kotlin", "Message", 0) }
Here we declare the Windows MessageBoxA
API as external
.
The function is loaded from user32.dll. This demonstrates platform-specific
interoperability in Kotlin.
Best Practices for external
- Use sparingly: Only use
external
when necessary for interoperability. - Document thoroughly: Clearly document native requirements and calling conventions.
- Handle errors: Implement proper error handling for native calls.
- Consider alternatives: Evaluate Kotlin multiplatform libraries before using native code.
- Test thoroughly: Native code can cause crashes - test extensively.
Source
Kotlin Native Interop Documentation
This tutorial covered Kotlin's external
keyword in depth, showing
its use for JNI, JavaScript, and platform interoperability. We explored various
scenarios including functions, properties, classes, and companion objects.
Proper use of external
enables powerful native integration.
Author
List all Kotlin tutorials.