or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

callable-system.mdclass-introspection.mdcore-reflection.mdindex.mdjvm-interoperability.mdtype-system.md

jvm-interoperability.mddocs/

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

```