0
# JVM Interoperability
1
2
Seamless bridge between Kotlin and Java reflection APIs, providing bidirectional conversion and access to JVM-specific features like accessibility control and type erasure.
3
4
## Capabilities
5
6
### Kotlin to Java Mapping
7
8
Convert Kotlin reflection objects to their Java reflection equivalents.
9
10
```kotlin { .api }
11
/** Returns Java Field instance for property backing field, or null */
12
val KProperty<*>.javaField: Field?
13
14
/** Returns Java Method instance for property getter, or null */
15
val KProperty<*>.javaGetter: Method?
16
17
/** Returns Java Method instance for mutable property setter, or null */
18
val KMutableProperty<*>.javaSetter: Method?
19
20
/** Returns Java Method instance for function, or null if constructor */
21
val KFunction<*>.javaMethod: Method?
22
23
/** Returns Java Constructor instance for function, or null if not constructor */
24
val <T> KFunction<T>.javaConstructor: Constructor<T>?
25
26
/** Returns Java Type instance corresponding to this KType */
27
val KType.javaType: Type
28
29
/** Returns JVM name of the class represented by this KClass */
30
val KClass<*>.jvmName: String
31
```
32
33
**Usage Examples:**
34
35
```kotlin
36
class Person(val name: String) {
37
var age: Int = 0
38
39
fun greet(): String = "Hello, $name"
40
41
constructor(name: String, age: Int) : this(name) {
42
this.age = age
43
}
44
}
45
46
val personClass = Person::class
47
48
// Property to Java Field/Method mapping
49
val nameProperty = Person::name
50
val ageProperty = Person::age
51
52
val nameField = nameProperty.javaField
53
val nameGetter = nameProperty.javaGetter
54
val ageSetter = (ageProperty as? KMutableProperty<*>)?.javaSetter
55
56
println("Name field: ${nameField?.name}") // "name"
57
println("Name getter: ${nameGetter?.name}") // "getName"
58
println("Age setter: ${ageSetter?.name}") // "setAge"
59
60
// Function to Java Method mapping
61
val greetFunction = Person::greet
62
val javaMethod = greetFunction.javaMethod
63
println("Java method: ${javaMethod?.name}") // "greet"
64
65
// Constructor to Java Constructor mapping
66
val constructor = personClass.constructors.find { it.parameters.size == 3 }
67
val javaConstructor = constructor?.javaConstructor
68
println("Java constructor params: ${javaConstructor?.parameterCount}") // 2
69
70
// Type to Java Type mapping
71
val stringType = typeOf<String>()
72
val javaType = stringType.javaType
73
println("Java type: $javaType") // class java.lang.String
74
75
// Class JVM name
76
println("JVM name: ${personClass.jvmName}") // "Person"
77
```
78
79
### Java to Kotlin Mapping
80
81
Convert Java reflection objects to their Kotlin reflection equivalents.
82
83
```kotlin { .api }
84
/** Returns KProperty instance for Java field, or null if not representable */
85
val Field.kotlinProperty: KProperty<*>?
86
87
/** Returns KFunction instance for Java method, or null if not representable */
88
val Method.kotlinFunction: KFunction<*>?
89
90
/** Returns KFunction instance for Java constructor, or null if not representable */
91
val <T : Any> Constructor<T>.kotlinFunction: KFunction<T>?
92
```
93
94
**Usage Examples:**
95
96
```kotlin
97
class Sample {
98
val readOnlyProperty: String = "value"
99
var mutableProperty: Int = 42
100
101
fun sampleMethod(param: String): Int = param.length
102
}
103
104
val sampleClass = Sample::class.java
105
106
// Java Field to Kotlin Property
107
val javaFields = sampleClass.declaredFields
108
javaFields.forEach { field ->
109
val kotlinProperty = field.kotlinProperty
110
println("Field ${field.name} -> Kotlin property: ${kotlinProperty?.name}")
111
}
112
113
// Java Method to Kotlin Function
114
val javaMethods = sampleClass.declaredMethods
115
javaMethods.forEach { method ->
116
val kotlinFunction = method.kotlinFunction
117
if (kotlinFunction != null) {
118
println("Method ${method.name} -> Kotlin function: ${kotlinFunction.name}")
119
}
120
}
121
122
// Java Constructor to Kotlin Function
123
val javaConstructors = sampleClass.declaredConstructors
124
javaConstructors.forEach { constructor ->
125
val kotlinFunction = constructor.kotlinFunction
126
println("Constructor -> Kotlin function: ${kotlinFunction != null}")
127
}
128
```
129
130
### JVM Type Operations
131
132
Access JVM-specific type information including type erasure.
133
134
```kotlin { .api }
135
/** Returns the KClass representing the runtime class this type is erased to on JVM */
136
val KType.jvmErasure: KClass<*>
137
```
138
139
**Usage Examples:**
140
141
```kotlin
142
// Type erasure examples
143
val stringType = typeOf<String>()
144
val listType = typeOf<List<String>>()
145
val mapType = typeOf<Map<String, Int>>()
146
147
println("String erasure: ${stringType.jvmErasure}") // class kotlin.String
148
println("List erasure: ${listType.jvmErasure}") // interface kotlin.collections.List
149
println("Map erasure: ${mapType.jvmErasure}") // interface kotlin.collections.Map
150
151
// Complex generic type erasure
152
val complexType = typeOf<List<Map<String, List<Int>>>>()
153
println("Complex type erasure: ${complexType.jvmErasure}") // interface kotlin.collections.List
154
155
// Nullable type erasure
156
val nullableType = typeOf<String?>()
157
println("Nullable erasure: ${nullableType.jvmErasure}") // class kotlin.String
158
```
159
160
### Accessibility Control
161
162
Control JVM access checks for reflective operations.
163
164
```kotlin { .api }
165
/**
166
* Provides a way to suppress JVM access checks for a callable
167
* For properties, affects all accessors (getter, setter, backing field)
168
*/
169
var KCallable<*>.isAccessible: Boolean
170
```
171
172
**Usage Examples:**
173
174
```kotlin
175
class PrivateExample {
176
private val privateProperty: String = "secret"
177
private fun privateMethod(): String = "private result"
178
}
179
180
val example = PrivateExample()
181
val clazz = PrivateExample::class
182
183
// Access private property
184
val privateProperty = clazz.memberProperties.find { it.name == "privateProperty" }
185
if (privateProperty != null) {
186
try {
187
// This would normally throw IllegalCallableAccessException
188
val value = privateProperty.get(example)
189
} catch (e: Exception) {
190
println("Access denied: ${e.message}")
191
}
192
193
// Make accessible and try again
194
privateProperty.isAccessible = true
195
val value = privateProperty.get(example)
196
println("Private property value: $value") // "secret"
197
}
198
199
// Access private function
200
val privateFunction = clazz.memberFunctions.find { it.name == "privateMethod" }
201
if (privateFunction != null) {
202
privateFunction.isAccessible = true
203
val result = privateFunction.call(example)
204
println("Private method result: $result") // "private result"
205
}
206
```
207
208
### Annotation Access
209
210
Access annotations through both Kotlin and Java reflection APIs.
211
212
```kotlin { .api }
213
/**
214
* Returns an annotation of the given type on this element
215
*/
216
inline fun <reified T : Annotation> KAnnotatedElement.findAnnotation(): T?
217
218
/**
219
* Returns true if this element is annotated with the given type
220
*/
221
inline fun <reified T : Annotation> KAnnotatedElement.hasAnnotation(): Boolean
222
223
/**
224
* Returns all annotations of the given type including repeated annotations
225
*/
226
inline fun <reified T : Annotation> KAnnotatedElement.findAnnotations(): List<T>
227
```
228
229
**Usage Examples:**
230
231
```kotlin
232
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
233
annotation class MyAnnotation(val value: String)
234
235
@Target(AnnotationTarget.FUNCTION)
236
annotation class Deprecated(val message: String)
237
238
@MyAnnotation("class-level")
239
class AnnotatedClass {
240
241
@MyAnnotation("property-level")
242
val annotatedProperty: String = "value"
243
244
@MyAnnotation("function-level")
245
@Deprecated("This method is deprecated")
246
fun annotatedMethod(): String = "result"
247
}
248
249
val clazz = AnnotatedClass::class
250
251
// Check class annotations
252
val classAnnotation = clazz.findAnnotation<MyAnnotation>()
253
println("Class annotation: ${classAnnotation?.value}") // "class-level"
254
255
val hasAnnotation = clazz.hasAnnotation<MyAnnotation>()
256
println("Class has annotation: $hasAnnotation") // true
257
258
// Check property annotations
259
val property = clazz.memberProperties.find { it.name == "annotatedProperty" }
260
val propertyAnnotation = property?.findAnnotation<MyAnnotation>()
261
println("Property annotation: ${propertyAnnotation?.value}") // "property-level"
262
263
// Check function annotations
264
val function = clazz.memberFunctions.find { it.name == "annotatedMethod" }
265
val functionAnnotations = function?.findAnnotations<MyAnnotation>()
266
println("Function annotations: ${functionAnnotations?.size}") // 1
267
268
val deprecatedAnnotation = function?.findAnnotation<Deprecated>()
269
println("Deprecated message: ${deprecatedAnnotation?.message}") // "This method is deprecated"
270
```
271
272
### Exception Types
273
274
Handle JVM reflection specific exceptions.
275
276
```kotlin { .api }
277
/**
278
* Thrown when call is invoked on a callable that is not accessible
279
*/
280
class IllegalCallableAccessException(cause: IllegalAccessException) : Exception
281
282
/**
283
* Thrown when getDelegate is invoked on a non-accessible property
284
*/
285
class IllegalPropertyDelegateAccessException(cause: IllegalAccessException) : Exception
286
287
/**
288
* Thrown when introspecting a property that no longer exists
289
*/
290
class NoSuchPropertyException(cause: Exception? = null) : Exception
291
```
292
293
**Usage Examples:**
294
295
```kotlin
296
class ExampleClass {
297
private val privateProperty: String = "private"
298
}
299
300
val clazz = ExampleClass::class
301
val instance = ExampleClass()
302
303
// Attempt to access private property without making it accessible
304
val privateProperty = clazz.memberProperties.find { it.name == "privateProperty" }
305
306
try {
307
val value = privateProperty?.get(instance)
308
} catch (e: IllegalCallableAccessException) {
309
println("Access exception: ${e.message}")
310
println("Caused by: ${e.cause}")
311
312
// Make accessible and retry
313
privateProperty?.isAccessible = true
314
val value = privateProperty.get(instance)
315
println("Successfully accessed: $value")
316
}
317
318
### Lambda Reflection
319
320
Experimental API for reflecting on lambda expressions and function instances.
321
322
```kotlin { .api }
323
/**
324
* Experimental API to get KFunction instance for compiled lambda or function expression
325
* Note: call() and callBy() are not currently supported
326
*/
327
@ExperimentalReflectionOnLambdas
328
fun <R> Function<R>.reflect(): KFunction<R>?
329
330
/**
331
* Annotation marking experimental lambda reflection API
332
*/
333
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
334
annotation class ExperimentalReflectionOnLambdas
335
```
336
337
**Usage Examples:**
338
339
```kotlin
340
@OptIn(ExperimentalReflectionOnLambdas::class)
341
fun demonstrateLambdaReflection() {
342
val lambda: (String) -> Int = { it.length }
343
344
// Reflect on lambda
345
val reflected = lambda.reflect()
346
347
if (reflected != null) {
348
println("Lambda name: ${reflected.name}")
349
println("Parameters: ${reflected.parameters.size}")
350
println("Return type: ${reflected.returnType}")
351
}
352
}
353
```