This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git


The following commit(s) were added to refs/heads/main by this push:
     new e0cf1b2fc08 Add kotlin json blog (#503)
e0cf1b2fc08 is described below

commit e0cf1b2fc0857da2cad7298cf47b095ca7c0750b
Author: Shawn Yang <[email protected]>
AuthorDate: Tue Sep 8 10:44:20 2026 +0800

    Add kotlin json blog (#503)
---
 blog/2026-09-07-fory_kotlin_json.md                | 313 +++++++++++++++++++++
 .../2026-09-07-fory_kotlin_json.md                 | 313 +++++++++++++++++++++
 .../fory-kotlin-json/clients_string_throughput.png | Bin 0 -> 81372 bytes
 .../clients_utf8_bytes_throughput.png              | Bin 0 -> 82118 bytes
 .../blog/fory-kotlin-json/string_throughput.png    | Bin 0 -> 81454 bytes
 .../fory-kotlin-json/users_string_throughput.png   | Bin 0 -> 81690 bytes
 .../users_utf8_bytes_throughput.png                | Bin 0 -> 82003 bytes
 .../fory-kotlin-json/utf8_bytes_throughput.png     | Bin 0 -> 81565 bytes
 8 files changed, 626 insertions(+)

diff --git a/blog/2026-09-07-fory_kotlin_json.md 
b/blog/2026-09-07-fory_kotlin_json.md
new file mode 100644
index 00000000000..6733bdb5920
--- /dev/null
+++ b/blog/2026-09-07-fory_kotlin_json.md
@@ -0,0 +1,313 @@
+---
+slug: fory_kotlin_json
+title: "Introducing Apache Fory™ JSON Kotlin: Blazing-Fast JSON Serialization"
+description: "Fory JSON maps Kotlin models to standard JSON while preserving 
constructor defaults, nullability, value classes, and sealed hierarchies. Learn 
how to use it and explore Kotlin MediaContent and 1000 KB benchmark results."
+authors: [chaokunyang]
+tags: [fory, kotlin, java, json, serialization, performance]
+---
+
+**TL;DR**: Apache Fory JSON for Kotlin combines standard JSON interoperability 
with Kotlin constructor defaults, nullability, value classes, and sealed 
hierarchies. The JVM module supports String and direct UTF-8 APIs without 
requiring `kotlin-reflect`. In the benchmarks presented here, Fory JSON Kotlin 
1.7.1 delivers **3.63×–12.12× the throughput** of kotlinx.serialization, Moshi, 
and Jackson Kotlin on MediaContent, and **2.78×–9.75×** on 1000 KB Users and 
Clients documents.
+
+- GitHub: [apache/fory](https://github.com/apache/fory)
+- Documentation: [Fory JSON for Kotlin](/docs/json/kotlin)
+- Measurements: [Kotlin JSON benchmark 
report](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/README.md)
+
+<img src="/img/fory-logo-light.png" width="50%"/>
+
+---
+
+## Kotlin Models as JSON Contracts
+
+A Kotlin data class describes how an object should be constructed as well as 
the values it contains. Required parameters must be supplied, defaults apply to 
omitted members, and nullability determines whether an explicit null is valid. 
These rules matter when a JSON document becomes an application object.
+
+Apache Fory JSON maps those models to standard JSON text and UTF-8 bytes. Its 
Kotlin module interprets the declared Kotlin types and invokes normal 
construction, preserving initialization and validation. Applications can 
therefore use constructor-based models directly, including classes with 
required `val` properties.
+
+The module adds Kotlin type handling to Fory's existing JSON runtime. 
Applications use the same parsing and output engine as the Java implementation, 
with construction guided by Kotlin metadata.
+
+## Getting Started
+
+Add the Kotlin JSON module, keeping all Fory dependencies on the same version:
+
+```kotlin title="build.gradle.kts"
+plugins {
+  kotlin("jvm") version "2.3.20"
+}
+
+repositories {
+  mavenCentral()
+}
+
+dependencies {
+  implementation("org.apache.fory:fory-json-kotlin:1.7.1")
+}
+```
+
+Create a runtime and a type token for the model. The runtime is immutable and 
thread-safe; retain both objects for repeated use:
+
+```kotlin
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+data class Account(
+  val id: ULong,
+  val name: String,
+  val nickname: String? = null,
+)
+
+val json = ForyJsonKotlin.builder().build()
+val accountType = jsonTypeRef<Account>()
+
+fun main() {
+  val input = Account(7uL, "Alice")
+
+  val text = json.toJson(input, accountType)
+  val utf8 = json.toJsonBytes(input, accountType)
+
+  val fromText = json.fromJson(text, accountType)
+  val fromUtf8 = json.fromJson(utf8, accountType)
+
+  check(fromText == input)
+  check(fromUtf8 == input)
+  println(fromText.name) // Alice
+}
+```
+
+This example needs no model annotations or serialization compiler plugin on a 
standard JVM. `ForyJsonKotlin.builder()` installs the Kotlin module, and 
`jsonTypeRef<Account>()` preserves the declared model's unsigned and nullable 
types. A Java `Class` alone cannot express all of those distinctions.
+
+The String and byte-array methods produce the same JSON representation. The 
byte methods operate directly on UTF-8, which avoids an intermediate String 
when an HTTP client, message transport, or storage API already exchanges bytes.
+
+## Constructor Defaults and Nullability
+
+The declared type determines how missing members are handled. For the 
following request, `id` is required, while `label` and `retries` have compiler 
defaults:
+
+```kotlin
+data class Request(
+  val id: Long,
+  val label: String? = "new",
+  val retries: Int = 3,
+)
+```
+
+Fory selects the primary constructor automatically. An absent member invokes 
its default when one exists; an explicit JSON null is checked against the 
parameter's nullability:
+
+| JSON input | Result |
+| --- | --- |
+| `{"id":1}` | `Request(1, "new", 3)` |
+| `{"id":1,"label":null}` | `Request(1, null, 3)` |
+| `{"label":"ready"}` | Rejected: required `id` is missing |
+| `{"id":1,"retries":null}` | Rejected: `retries` is non-null |
+
+This distinction also affects serialization. If `label` is null, omitting it 
would cause a reader to restore `"new"`. Fory therefore writes nullable 
constructor properties explicitly when they contain null, so its output 
reconstructs the same value under the same configuration.
+
+Nullability and defaults remain independent: a nullable parameter without a 
default still requires a JSON member. The same type information extends into 
containers. `jsonTypeRef<List<Account?>>()` permits null elements, while 
`jsonTypeRef<List<Account>>()` rejects them. Retaining the full declared type 
preserves these rules through nested generic models.
+
+The [Kotlin guide](/docs/json/kotlin#immutable-classes-and-compiler-defaults) 
covers secondary constructors, explicit creators, and properties declared in 
the class body.
+
+## Preserving Domain Types
+
+Value classes allow an application to distinguish domain identifiers without 
adding another object to the JSON document. Fory maps an eligible value class 
to its underlying value and runs its initialization checks during 
reconstruction:
+
+```kotlin
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+@JvmInline
+value class AccountId(val value: ULong) {
+  init {
+    require(value > 0uL)
+  }
+}
+
+val json = ForyJsonKotlin.builder().build()
+val idType = jsonTypeRef<AccountId>()
+
+val text = json.toJson(AccountId(42uL), idType) // 42
+val restored = json.fromJson(text, idType)
+```
+
+Here, `AccountId` remains a distinct application type, while its JSON 
representation is the number `42`. The type token retains that identity even 
when the JVM represents the value through a primitive carrier.
+
+Unsigned integers preserve their decimal representation, including the full 
`ULong` range. When an API requires 64-bit integers as JSON strings, 
`ForyJsonKotlin.builder().writeLongAsString(true)` applies that representation 
to `Long` and `ULong`, including supported containers and value classes. 
Readers accept either quoted or unquoted integer tokens.
+
+Automatic mapping must have an unambiguous representation. A nullable value 
class with a nullable underlying value would give two distinct states the same 
JSON null, so that case requires a tagged custom codec. The [type support 
table](/docs/json/kotlin#supported-kotlin-types) documents the remaining Kotlin 
types and their representations.
+
+## Sealed Types and JSON Annotations
+
+Some API values have several possible shapes. A Kotlin sealed hierarchy 
defines those alternatives in the model itself. Annotating its base with 
`JsonSubTypes` lets Fory infer the concrete variants:
+
+```kotlin
+import org.apache.fory.json.annotation.JsonSubTypes
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+@JsonSubTypes(property = "kind")
+sealed interface Payment
+
+data class CardPayment(val lastFour: String) : Payment
+data class BankTransfer(val account: String) : Payment
+
+val json = ForyJsonKotlin.builder().build()
+val paymentType = jsonTypeRef<Payment>()
+
+val text = json.toJson(CardPayment("4242"), paymentType)
+// {"kind":"CardPayment","lastFour":"4242"}
+val decoded = json.fromJson(text, paymentType)
+```
+
+Using the declared `Payment` type selects the subtype table. The `kind` 
property contains a logical variant name, and unknown names are rejected. JSON 
input cannot supply an arbitrary JVM class. Inferred names follow source class 
names; an explicit subtype table provides stable wire names when an API must 
remain independent of source renaming. The same mapping applies within 
`jsonTypeRef<List<Payment>>()`.
+
+Annotations can also align individual Kotlin properties with an existing JSON 
contract. An explicit use-site target identifies the JVM element that should 
receive the annotation:
+
+```kotlin
+import org.apache.fory.json.annotation.JsonProperty
+
+data class Profile(
+  @param:JsonProperty("user_id")
+  val id: Long,
+  val name: String,
+)
+```
+
+In this example, the constructor parameter `id` maps to the JSON member 
`user_id`. Naming, formatting, Mixins, and custom codecs use Fory's shared 
annotation system. The [annotation 
guide](/docs/json/annotations#kotlin-use-site-targets) explains the supported 
Kotlin targets and how they combine.
+
+## How Fory JSON Achieves High Performance in Kotlin
+
+Fory's Kotlin support connects language-aware object mapping to an optimized 
JSON engine. The Kotlin module determines how a declared type should be 
represented and constructed; the shared runtime specializes the repeated work 
of reading and writing that representation. This design reduces model 
discovery, dispatch, text processing, and temporary allocation while preserving 
Kotlin's construction rules.
+
+### Preparing Kotlin Types Once
+
+When preparing a codec, the Kotlin module reads class metadata and resolves 
the constructor, property accessors, exact generic bindings, nullability, and 
parameters with compiler defaults. It translates this information into the 
runtime's object model. Retaining the runtime and `jsonTypeRef<T>()` allows 
subsequent operations to reuse the resolved codecs without repeating that 
metadata analysis.
+
+For the `Request` example, the prepared model already identifies `id` as 
required and records how to invoke the defaults for `label` and `retries`. Each 
read still checks which members are present and whether their values are valid. 
Default expressions execute when construction requires them; their results are 
not cached. The saved work is rediscovering the rules, while the rules 
themselves remain part of deserialization.
+
+### Generating Code for the Declared Model
+
+On a standard JDK, Fory generates and compiles codecs specialized for the 
target model. Generated writers use known property accessors and concrete 
primitive operations. Property names, quotes, colons, and separators can be 
prepared as encoded prefixes, allowing a field such as `"id":` to be emitted 
through packed writes instead of repeated escaping and individual character 
writes.
+
+Generated readers likewise specialize property matching and value decoding for 
the declared schema. They read constructor arguments, track absent parameters, 
and invoke the selected constructor or its compiler-generated default form. 
Common property matches use prepared names and direct input probes, reducing 
repeated name decoding and generic lookup. Other field orders and escaped names 
remain supported through fallback paths.
+
+This specialization gives the JVM concrete operations to optimize while 
preserving normal Kotlin initialization and validation. Runtime generation is 
enabled by default on standard JDKs; an interpreted path supports environments 
where runtime compilation is unavailable.
+
+### Processing Numbers and Text Directly
+
+Integer and long writers encode decimal digits directly into the output 
buffer, including the unsigned representations used by Kotlin. Floating-point 
writers use direct formatting paths where the JDK supports them. Common scalar 
writes therefore avoid creating a temporary String for each value. Integer 
readers also parse digits from the input directly, with syntax and overflow 
checks, instead of allocating a numeric substring first.
+
+Text processing uses bulk operations on common ASCII and Latin-1 paths. For 
example, the UTF-8 writer scans ASCII text in 8-byte or 16-byte groups to 
detect characters that require escaping, then copies eligible spans in bulk. 
Escapes and non-ASCII characters follow the appropriate encoding paths. 
Together with prepared property prefixes, this reduces per-character branching 
and copying overhead across the repeated names and text values in structured 
JSON.
+
+### Reusing Buffers and Keeping UTF-8 Direct
+
+A reusable `ForyJson` runtime retains execution states containing readers, 
writers, resolver caches, and output buffers. Each active operation has 
exclusive use of its borrowed state. Subsequent calls can reuse that working 
storage, reducing temporary allocation and garbage-collection pressure. 
Returning a String or byte array still allocates the requested result; buffer 
growth and constructing the deserialized object graph also require memory.
+
+The byte APIs preserve these paths through the complete operation. 
`toJsonBytes` writes JSON directly into a UTF-8 buffer, and `fromJson` reads 
UTF-8 bytes directly into the declared Kotlin model. Typed object mapping does 
not require an intermediate JSON tree or a String representation of the 
complete document. This matters when a service already receives or sends bytes, 
especially for the larger Users and Clients documents below.
+
+## Performance on Kotlin Models
+
+The following benchmarks measure these mechanisms together on Kotlin models. 
MediaContent covers smaller structured messages, while Users and Clients 
exercise repeated records, collections, and JDK value types in documents of 
approximately 1 MB. The results measure complete library operations and do not 
isolate the contribution of each optimization.
+
+### Benchmark Setup
+
+The Kotlin runs compare Fory JSON Kotlin 1.7.1, kotlinx.serialization 1.11.0, 
Moshi 1.15.2 with generated adapters, and Jackson Kotlin 2.22.1. Both used an 
Apple M5 and OpenJDK 25.0.3. JMH 1.37 ran one fork and one thread, with three 
2-second warmup iterations and five 2-second measurement iterations.
+
+All libraries process the same Kotlin models with required constructor 
arguments and the same input within each workload. Codecs, serializers, 
adapters, and typed readers/writers are prepared before timing, including 
Fory's runtime code generation. Setup verifies fixture reads, round trips, and 
equivalent JSON output. The checks follow the [Apache Fory Kotlin benchmark 
methodology](/docs/benchmarks/json/kotlin/).
+
+String operations exclude UTF-8 conversion. For byte operations, Fory and 
Jackson use direct byte-array APIs, kotlinx.serialization uses `encodeToStream` 
and `decodeFromStream`, and Moshi uses an Okio `Buffer`. Stream and buffer 
creation and byte-array extraction are included in the measurement; these paths 
do not convert through an intermediate String.
+
+Tables report operations per second, rounded to the nearest whole operation; 
higher is better. Charts show the errors reported by JMH. Full measurements, 
environment records, and reproduction commands are available in the [benchmark 
report](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/README.md).
+
+### MediaContent: Structured Messages
+
+The Eishay MediaContent fixture contains a media record and images, with 
strings, numbers, lists, and enums. Its Kotlin models use required constructor 
arguments and `val` properties. The fixture also exercises nullable members and 
constructor defaults, with null and default output configured consistently 
across libraries.
+
+![Kotlin MediaContent String serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/string_throughput.png)
+
+![Kotlin MediaContent UTF-8 byte serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/utf8_bytes_throughput.png)
+
+| Representation | Operation | Fory JSON Kotlin ops/s | kotlinx.serialization 
ops/s | Moshi ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | Serialize | 8,463,544 | 2,331,337 | 1,009,654 | 2,166,486 |
+| String | Deserialize | 3,963,797 | 631,164 | 513,445 | 508,099 |
+| UTF-8 bytes | Serialize | 12,314,484 | 1,059,643 | 1,015,884 | 1,954,090 |
+| UTF-8 bytes | Deserialize | 4,449,742 | 729,606 | 701,187 | 531,665 |
+
+Fory records the highest throughput in all four operations, reaching **12.31 
million UTF-8 serializations per second**. Its largest serialization advantage 
is on the byte API: 11.62× kotlinx.serialization's throughput and 12.12× 
Moshi's. On byte deserialization, it reaches 8.37× Jackson Kotlin's throughput.
+
+### Users and Clients: Larger Documents
+
+The larger suite ports the Users and Clients schemas from 
`java-json-benchmark` to Kotlin data classes. Users contains text fields, 
numeric values, tags, and nested friends. Clients adds JDK value types such as 
`UUID`, `BigDecimal`, `LocalDate`, and `OffsetDateTime`, together with enums, 
arrays, and nested partners.
+
+Each operation processes a complete document. The deterministic generator 
appends records until the compact UTF-8 input reaches at least 1,000,000 bytes:
+
+| Kotlin model | UTF-8 document size | Records |
+| --- | ---: | ---: |
+| Users | 1,001,958 bytes | 431 |
+| Clients | 1,000,779 bytes | 379 |
+
+Fory uses its built-in JDK codecs. kotlinx.serialization and Moshi use 
explicit adapters for UUIDs and dates as strings and `BigDecimal` as an 
unquoted number without losing decimal digits. Jackson registers 
`JavaTimeModule` 2.22.1. Correctness checks compare array contents and complete 
`OffsetDateTime` values, allowing equivalent timestamp spellings with different 
trailing fractional zeros.
+
+#### Users
+
+![Kotlin Users String serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/users_string_throughput.png)
+
+![Kotlin Users UTF-8 byte serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/users_utf8_bytes_throughput.png)
+
+| Representation | Operation | Fory JSON Kotlin ops/s | kotlinx.serialization 
ops/s | Moshi ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | Serialize | 3,132 | 520 | 625 | 1,128 |
+| String | Deserialize | 1,782 | 509 | 443 | 371 |
+| UTF-8 bytes | Serialize | 3,536 | 384 | 639 | 1,003 |
+| UTF-8 bytes | Deserialize | 2,046 | 480 | 590 | 396 |
+
+On Users, Fory's UTF-8 serialization throughput is 9.21× that of 
kotlinx.serialization, 5.53× that of Moshi, and 3.52× that of Jackson Kotlin. 
It also leads both deserialization operations, where the workload includes 
constructing the nested records and collections.
+
+#### Clients
+
+![Kotlin Clients String serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/clients_string_throughput.png)
+
+![Kotlin Clients UTF-8 byte serialization and deserialization 
throughput](/img/blog/fory-kotlin-json/clients_utf8_bytes_throughput.png)
+
+| Representation | Operation | Fory JSON Kotlin ops/s | kotlinx.serialization 
ops/s | Moshi ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | Serialize | 2,393 | 549 | 496 | 724 |
+| String | Deserialize | 1,955 | 258 | 217 | 200 |
+| UTF-8 bytes | Serialize | 3,947 | 418 | 499 | 621 |
+| UTF-8 bytes | Deserialize | 2,070 | 256 | 253 | 215 |
+
+On Clients String deserialization, Fory reaches **7.59× kotlinx.serialization, 
8.99× Moshi, and 9.75× Jackson Kotlin**. These measurements extend the 
comparison to models containing JDK values and arrays as well as text and 
collections. All 32 Users/Clients cases completed, producing 160 measurement 
samples.
+
+### Interpreting the Results
+
+Across each workload's four operations, Fory's throughput relative to the 
other libraries falls within the following ranges. Ratios are calculated from 
unrounded scores:
+
+| Kotlin model | vs. kotlinx.serialization | vs. Moshi | vs. Jackson Kotlin |
+| --- | ---: | ---: | ---: |
+| MediaContent | 3.63×–11.62× | 6.35×–12.12× | 3.91×–8.37× |
+| Users | 3.50×–9.21× | 3.47×–5.53× | 2.78×–5.16× |
+| Clients | 4.36×–9.45× | 4.83×–8.99× | 3.31×–9.75× |
+
+The 1000 KB Kotlin results span **2.78×–9.75×** the throughput of the compared 
libraries. These are measurements of the selected models and configurations; 
performance for value classes and sealed hierarchies is not measured by these 
workloads.
+
+The Users/Clients corpus follows the upstream field lengths, numeric ranges, 
and collection sizes, but uses its own deterministic generation sequence. Its 
[input hashes and environment 
record](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/results/users-clients/environment.json)
 identify the tested documents. The smaller MediaContent run has a separate 
[environment 
record](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/7139 [...]
+
+### Java Benchmark Context
+
+The shared engine also has published Java measurements. The table below 
summarizes Fory JSON's throughput relative to Jackson and Gson across the 
operations reported for each workload:
+
+| Java workload | vs. Jackson | vs. Gson |
+| --- | ---: | ---: |
+| [MediaContent: String and UTF-8](/docs/benchmarks/json/java/) | 2.43×–5.55× 
| 3.21×–10.00× |
+| [Users: 1000 
KB](https://github.com/fabienrenaud/java-json-benchmark/pull/129) | 3.54×–5.33× 
| 5.65×–7.09× |
+| [Clients: 1000 
KB](https://github.com/fabienrenaud/java-json-benchmark/pull/129) | 
6.97×–10.91× | 9.16×–10.89× |
+
+These are separate Java runs, with different library versions and measurement 
configurations. The large-document Java report uses Fory JSON 1.6.0; Gson's 
byte measurements in the Java MediaContent report include its required String 
conversion. The linked reports retain the full scores and setup. They provide 
context for the shared engine, rather than a Kotlin-versus-Java performance 
comparison.
+
+## JVM and Deployment Support
+
+The module targets Kotlin/JVM and does not require `kotlin-reflect`. Its 
runtime is built with Kotlin 2.3.20 and accepts model metadata supported by 
Kotlin's strict metadata reader. The [getting-started 
guide](/docs/json/getting-started) covers runtime configuration, including the 
recommended `java.lang.invoke` opening on JDK 25 and later.
+
+On Android API 26 and later, Fory uses interpreted JSON mapping. When R8 or 
ProGuard is enabled, add `fory-json-kotlin-ksp` and mark required source models 
with `JsonType` to preserve their mapping. GraalVM Native Image uses the 
`ForyJsonProvider` workflow: install the Kotlin module and select reachable 
models for code generation. The [Kotlin platform 
guide](/docs/json/kotlin#graalvm-and-android) provides the configuration for 
both environments. Kotlin/Native, Kotlin/JS, and Kotlin/Wasm  [...]
+
+## Learn More
+
+Fory JSON allows Kotlin applications to retain the meaning of their model 
declarations while exchanging standard JSON. Constructor defaults, nullability, 
value-class identity, and sealed alternatives remain part of the mapping, with 
String and UTF-8 APIs available through the same reusable runtime.
+
+The [Kotlin JSON guide](/docs/json/kotlin) provides the complete mapping and 
platform reference. For application-specific representations, see [Custom 
Codecs](/docs/json/custom-codecs); for input limits and type controls, see 
[Security](/docs/json/security). Source code and contribution instructions are 
available at [apache/fory](https://github.com/apache/fory).
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-07-fory_kotlin_json.md 
b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-07-fory_kotlin_json.md
new file mode 100644
index 00000000000..8b429781b9f
--- /dev/null
+++ b/i18n/zh-CN/docusaurus-plugin-content-blog/2026-09-07-fory_kotlin_json.md
@@ -0,0 +1,313 @@
+---
+slug: fory_kotlin_json
+title: "Apache Fory™ JSON Kotlin:极速 Kotlin JSON 序列化框架"
+description: "Fory JSON 将 Kotlin 模型映射为标准 JSON,同时保留构造函数默认值、可空性、值类和 sealed 
层次结构。本文介绍其使用方式、性能原理,以及 Kotlin MediaContent 和 1000 KB 文档的基准测试结果。"
+authors: [chaokunyang]
+tags: [fory, kotlin, java, json, serialization, performance]
+---
+
+**摘要**:Apache Fory JSON for Kotlin 在提供标准 JSON 互操作能力的同时,保留 Kotlin 
构造函数默认值、可空性、值类和 sealed 层次结构的语义。该 JVM 模块支持 String API 和直接处理 UTF-8 的 API,无需依赖 
`kotlin-reflect`。在本文展示的基准测试中,Fory JSON Kotlin 1.7.1 处理 MediaContent 时,吞吐量为 
kotlinx.serialization、Moshi 和 Jackson Kotlin 的 **3.63–12.12 倍**;处理 1000 KB 的 
Users 和 Clients 文档时,吞吐量为这些库的 **2.78–9.75 倍**。
+
+- GitHub:[apache/fory](https://github.com/apache/fory)
+- 文档:[Fory JSON for Kotlin](/docs/json/kotlin)
+- 测试数据:[Kotlin JSON 
基准测试报告](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/README.md)
+
+<img src="/img/fory-logo-light.png" width="50%"/>
+
+---
+
+## 以 Kotlin 模型定义 JSON 契约 {#kotlin-models-as-json-contracts}
+
+Kotlin 数据类既描述对象包含哪些值,也定义对象应当如何构造。必需参数必须提供,缺失成员可以使用默认值,可空性则决定显式 null 是否有效。将 
JSON 文档还原为应用对象时,这些规则同样需要得到遵守。
+
+Apache Fory JSON 将这些模型映射为标准 JSON 文本和 UTF-8 字节。Kotlin 模块解析声明的 Kotlin 
类型,并通过正常的构造过程创建对象,保留初始化和校验逻辑。因此,应用可以直接使用依赖构造函数的模型,包括具有必需 `val` 属性的类。
+
+该模块在 Fory 现有的 JSON 运行时上增加 Kotlin 类型处理能力。应用与 Java 实现共用解析和输出引擎,对象构造则由 Kotlin 
元数据指导。
+
+## 快速开始 {#getting-started}
+
+添加 Kotlin JSON 模块,并确保所有 Fory 依赖使用相同版本:
+
+```kotlin title="build.gradle.kts"
+plugins {
+  kotlin("jvm") version "2.3.20"
+}
+
+repositories {
+  mavenCentral()
+}
+
+dependencies {
+  implementation("org.apache.fory:fory-json-kotlin:1.7.1")
+}
+```
+
+创建运行时和模型的类型令牌。运行时不可变且线程安全;应保留这两个对象以便重复使用:
+
+```kotlin
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+data class Account(
+  val id: ULong,
+  val name: String,
+  val nickname: String? = null,
+)
+
+val json = ForyJsonKotlin.builder().build()
+val accountType = jsonTypeRef<Account>()
+
+fun main() {
+  val input = Account(7uL, "Alice")
+
+  val text = json.toJson(input, accountType)
+  val utf8 = json.toJsonBytes(input, accountType)
+
+  val fromText = json.fromJson(text, accountType)
+  val fromUtf8 = json.fromJson(utf8, accountType)
+
+  check(fromText == input)
+  check(fromUtf8 == input)
+  println(fromText.name) // Alice
+}
+```
+
+在标准 JVM 上,这个示例不需要模型注解或序列化编译器插件。`ForyJsonKotlin.builder()` 会安装 Kotlin 
模块,`jsonTypeRef<Account>()` 则保留声明模型中的无符号类型和可空类型信息。仅靠 Java `Class` 无法表达所有这些区别。
+
+String 方法和字节数组方法生成相同的 JSON 表示。字节方法直接处理 UTF-8,因此当 HTTP 客户端、消息传输或存储 API 
已经使用字节交换数据时,可以避免中间 String 转换。
+
+## 构造函数默认值与可空性 {#constructor-defaults-and-nullability}
+
+声明的类型决定如何处理缺失成员。在下面的请求模型中,`id` 是必需参数,`label` 和 `retries` 则具有编译器支持的默认值:
+
+```kotlin
+data class Request(
+  val id: Long,
+  val label: String? = "new",
+  val retries: Int = 3,
+)
+```
+
+Fory 自动选择主构造函数。成员缺失且存在默认值时,会使用该默认值;对于显式 JSON null,则根据参数的可空性进行检查:
+
+| JSON 输入 | 结果 |
+| --- | --- |
+| `{"id":1}` | `Request(1, "new", 3)` |
+| `{"id":1,"label":null}` | `Request(1, null, 3)` |
+| `{"label":"ready"}` | 拒绝:缺少必需参数 `id` |
+| `{"id":1,"retries":null}` | 拒绝:`retries` 不可空 |
+
+这一差异也影响序列化。如果 `label` 为 null,省略该成员会使读取方恢复出 `"new"`。因此,对于值为 null 的可空构造函数属性,Fory 
会显式写出 null,使输出在相同配置下能够还原为相同的值。
+
+可空性与默认值相互独立:没有默认值的可空参数仍要求 JSON 
中存在对应成员。相同的类型信息也会延伸到容器内部。`jsonTypeRef<List<Account?>>()` 允许 null 元素,而 
`jsonTypeRef<List<Account>>()` 会拒绝 null 元素。保留完整的声明类型,可以让这些规则在嵌套泛型模型中继续生效。
+
+关于次构造函数、显式创建器和类体中声明的属性,请参阅 [Kotlin 
指南](/docs/json/kotlin#immutable-classes-and-compiler-defaults)。
+
+## 保留领域类型 {#preserving-domain-types}
+
+值类让应用能够区分不同的领域标识符,同时无需在 JSON 文档中增加一层对象。Fory 将符合条件的值类映射为底层值,并在重建时执行其初始化检查:
+
+```kotlin
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+@JvmInline
+value class AccountId(val value: ULong) {
+  init {
+    require(value > 0uL)
+  }
+}
+
+val json = ForyJsonKotlin.builder().build()
+val idType = jsonTypeRef<AccountId>()
+
+val text = json.toJson(AccountId(42uL), idType) // 42
+val restored = json.fromJson(text, idType)
+```
+
+这里,`AccountId` 在应用中仍是独立的类型,其 JSON 表示则是数字 `42`。即使 JVM 
使用基本类型作为该值的底层载体,类型令牌仍会保留它的类型身份。
+
+无符号整数保留其十进制表示,包括完整的 `ULong` 取值范围。当 API 要求将 64 位整数表示为 JSON 
字符串时,`ForyJsonKotlin.builder().writeLongAsString(true)` 会将该表示方式应用于 `Long` 和 
`ULong`,也包括受支持的容器和值类。读取器同时接受带引号和不带引号的整数。
+
+自动映射要求 JSON 表示没有歧义。如果一个值类本身可空,且其底层值也可空,两个不同的状态就会对应同一个 JSON 
null,因此这种情况需要使用带标签的自定义编解码器。其他 Kotlin 
类型及其表示方式见[类型支持表](/docs/json/kotlin#supported-kotlin-types)。
+
+## sealed 类型与 JSON 注解 {#sealed-types-and-json-annotations}
+
+某些 API 值可能具有多种结构。Kotlin sealed 层次结构将这些可能的类型直接定义在模型中。在基类型上标注 
`JsonSubTypes`,Fory 即可推导出具体的变体:
+
+```kotlin
+import org.apache.fory.json.annotation.JsonSubTypes
+import org.apache.fory.json.kotlin.ForyJsonKotlin
+import org.apache.fory.json.kotlin.jsonTypeRef
+
+@JsonSubTypes(property = "kind")
+sealed interface Payment
+
+data class CardPayment(val lastFour: String) : Payment
+data class BankTransfer(val account: String) : Payment
+
+val json = ForyJsonKotlin.builder().build()
+val paymentType = jsonTypeRef<Payment>()
+
+val text = json.toJson(CardPayment("4242"), paymentType)
+// {"kind":"CardPayment","lastFour":"4242"}
+val decoded = json.fromJson(text, paymentType)
+```
+
+使用声明类型 `Payment` 时,会选用对应的子类型表。`kind` 属性包含变体的逻辑名称,未知名称会被拒绝。JSON 输入无法指定任意 JVM 
类。推导出的名称取自源码类名;如果 API 中的名称需要独立于源码重命名而保持稳定,可以显式声明子类型表。相同的映射也适用于 
`jsonTypeRef<List<Payment>>()`。
+
+注解还可以将单个 Kotlin 属性映射到现有的 JSON 契约。显式指定注解的使用位置目标,可以确定哪个 JVM 元素应接收该注解:
+
+```kotlin
+import org.apache.fory.json.annotation.JsonProperty
+
+data class Profile(
+  @param:JsonProperty("user_id")
+  val id: Long,
+  val name: String,
+)
+```
+
+在这个示例中,构造函数参数 `id` 映射为 JSON 成员 `user_id`。命名、格式化、Mixin 和自定义编解码器使用 Fory 
共用的注解体系。[注解指南](/docs/json/annotations#kotlin-use-site-targets)介绍了受支持的 Kotlin 
使用位置目标及其组合规则。
+
+## Fory JSON 如何在 Kotlin 中实现高性能 
{#how-fory-json-achieves-high-performance-in-kotlin}
+
+Fory 的 Kotlin 支持将遵循语言语义的对象映射与经过优化的 JSON 引擎结合起来。Kotlin 
模块确定声明类型的表示和构造方式,共用运行时则针对这种表示的反复读写生成专用处理逻辑。这一设计在保留 Kotlin 
构造规则的同时,减少了模型解析、调用分派、文本处理和临时分配的开销。
+
+### 预先解析并复用 Kotlin 类型信息 {#preparing-kotlin-types-once}
+
+准备编解码器时,Kotlin 
模块会读取类元数据,解析构造函数、属性访问器、精确的泛型绑定、可空性,以及哪些参数具有编译器支持的默认值,并将这些信息转换为运行时的对象模型。保留运行时和 
`jsonTypeRef<T>()`,后续操作便可复用已解析的编解码器,无需重复分析元数据。
+
+以前文的 `Request` 为例,准备好的模型已经确定 `id` 是必需参数,并记录了如何调用 `label` 和 `retries` 
的默认值逻辑。每次读取仍会检查哪些成员存在,以及它们的值是否有效。构造过程需要默认值时,仍会执行默认值表达式,其计算结果不会被缓存。被省去的是反复解析规则的工作,规则本身仍在反序列化过程中生效。
+
+### 为声明模型生成专用代码 {#generating-code-for-the-declared-model}
+
+在标准 JDK 上,Fory 
会为目标模型生成并编译专用编解码器。生成的写入器使用已知的属性访问器和具体的基本类型操作。属性名、引号、冒号和分隔符可以预先编码为前缀,使 `"id":` 
这样的字段前缀通过打包写入输出,无需反复转义或逐个字符写入。
+
+生成的读取器也会针对声明的 Schema 
专门处理属性匹配和值解码。它们读取构造函数参数,记录缺失参数,并调用选定的构造函数或编译器生成的默认参数构造形式。常见属性通过预先准备的名称和对输入的直接检查进行匹配,从而减少重复的名称解码和通用查找。其他字段顺序及带转义的名称仍可通过回退路径处理。
+
+这些专用代码为 JVM 提供了可进一步优化的具体操作,同时保留正常的 Kotlin 初始化和校验逻辑。标准 JDK 
默认启用运行时代码生成;无法在运行时编译的环境则可以使用解释执行路径。
+
+### 直接处理数字和文本 {#processing-numbers-and-text-directly}
+
+整数和长整数写入器将十进制数字直接编码到输出缓冲区,也支持 Kotlin 使用的无符号表示。JDK 
提供相应能力时,浮点数写入器采用直接格式化路径。因此,常见标量的写入无需为每个值创建临时 
String。整数读取器也直接从输入中解析数字,并执行语法和溢出检查,无需先分配用于表示该数字的子字符串。
+
+在常见的 ASCII 和 Latin-1 路径上,文本通过批量操作处理。例如,UTF-8 写入器以 8 字节或 16 字节为一组扫描 ASCII 
文本,检测需要转义的字符,再批量复制符合条件的片段。转义字符和非 ASCII 字符则由相应的编码路径处理。结合预先准备的属性前缀,这些操作可以降低结构化 
JSON 中重复名称和文本值的逐字符分支与复制开销。
+
+### 复用缓冲区并直接处理 UTF-8 {#reusing-buffers-and-keeping-utf-8-direct}
+
+可复用的 `ForyJson` 
运行时会保留执行状态,其中包含读取器、写入器、类型解析器缓存和输出缓冲区。每个执行中的操作独占其借用的状态。后续调用可以复用这些工作内存,减少临时分配和垃圾回收压力。返回
 String 或字节数组时,仍需为结果分配内存;缓冲区扩容和反序列化对象图的构建也需要内存。
+
+字节 API 在整个操作中保留这些处理路径。`toJsonBytes` 直接将 JSON 写入 UTF-8 缓冲区,`fromJson` 则直接读取 
UTF-8 字节并构造声明的 Kotlin 模型。按类型进行对象映射无需构建中间 JSON 树,也无需将完整文档转换为 
String。对于本身就以字节收发数据的服务,这一点尤为重要,下文较大的 Users 和 Clients 文档便属于此类场景。
+
+## Kotlin 模型的性能表现 {#performance-on-kotlin-models}
+
+下面的基准测试衡量这些机制在 Kotlin 模型上共同运行时的性能。MediaContent 覆盖较小的结构化消息;Users 和 Clients 则通过约 
1 MB 的文档,测试重复记录、集合和 JDK 值类型。结果反映各库完整操作的性能,并未单独测量每项优化的贡献。
+
+### 基准测试配置 {#benchmark-setup}
+
+Kotlin 测试比较 Fory JSON Kotlin 1.7.1、kotlinx.serialization 1.11.0、使用生成式适配器的 
Moshi 1.15.2,以及 Jackson Kotlin 2.22.1。两次测试均使用 Apple M5 和 OpenJDK 25.0.3。JMH 
1.37 运行一个 fork 和一个线程,包含三轮 2 秒预热迭代和五轮 2 秒测量迭代。
+
+所有库处理相同的 Kotlin 
模型,这些模型均包含必需的构造函数参数;同一负载下,各库也使用相同的输入。编解码器、序列化器、适配器和具有明确类型的读取器、写入器均在计时前准备完成,包括 
Fory 的运行时代码生成。准备阶段验证测试样本的读取、往返转换和 JSON 输出的等价性,遵循 [Apache Fory Kotlin 
基准测试方法](/docs/benchmarks/json/kotlin/)。
+
+String 操作不包含 UTF-8 转换。字节操作中,Fory 和 Jackson 使用直接字节数组 API,kotlinx.serialization 
使用 `encodeToStream` 和 `decodeFromStream`,Moshi 使用 Okio 
`Buffer`。流与缓冲区的创建、字节数组的提取均计入测量;这些路径都不经过中间 String 转换。
+
+表格以每秒操作数(ops/s)报告吞吐量,四舍五入到整数,数值越高越好。图中展示 JMH 
报告的误差。完整测量数据、环境记录和复现命令见[基准测试报告](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/README.md)。
+
+### MediaContent:结构化消息 {#mediacontent-structured-messages}
+
+Eishay MediaContent 测试样本包含一条媒体记录和图像,涉及字符串、数字、列表和枚举。其 Kotlin 模型使用必需构造函数参数和 
`val` 属性,同时涵盖可空成员和构造函数默认值。各库的 null 与默认值输出配置保持一致。
+
+![Kotlin MediaContent String 
序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/string_throughput.png)
+
+![Kotlin MediaContent UTF-8 
字节序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/utf8_bytes_throughput.png)
+
+| 表示形式 | 操作 | Fory JSON Kotlin ops/s | kotlinx.serialization ops/s | Moshi 
ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | 序列化 | 8,463,544 | 2,331,337 | 1,009,654 | 2,166,486 |
+| String | 反序列化 | 3,963,797 | 631,164 | 513,445 | 508,099 |
+| UTF-8 字节 | 序列化 | 12,314,484 | 1,059,643 | 1,015,884 | 1,954,090 |
+| UTF-8 字节 | 反序列化 | 4,449,742 | 729,606 | 701,187 | 531,665 |
+
+Fory 在四项操作中均取得最高吞吐量,UTF-8 序列化达到**每秒 1,231 万次**。其序列化优势在字节 API 上最为明显:吞吐量分别为 
kotlinx.serialization 的 11.62 倍和 Moshi 的 12.12 倍。字节反序列化吞吐量则为 Jackson Kotlin 的 
8.37 倍。
+
+### Users 和 Clients:更大的文档 {#users-and-clients-larger-documents}
+
+大文档测试将 `java-json-benchmark` 中的 Users 和 Clients Schema 移植为 Kotlin 数据类。Users 
包含文本字段、数值、标签和嵌套的朋友记录。Clients 还包含 `UUID`、`BigDecimal`、`LocalDate` 和 
`OffsetDateTime` 等 JDK 值类型,以及枚举、数组和嵌套的合作伙伴记录。
+
+每次操作处理一份完整文档。确定性生成器持续追加记录,直到紧凑 UTF-8 输入至少达到 1,000,000 字节:
+
+| Kotlin 模型 | UTF-8 文档大小 | 记录数 |
+| --- | ---: | ---: |
+| Users | 1,001,958 字节 | 431 |
+| Clients | 1,000,779 字节 | 379 |
+
+Fory 使用内置 JDK 编解码器。kotlinx.serialization 和 Moshi 使用显式适配器,将 UUID 和日期表示为字符串,将 
`BigDecimal` 表示为不带引号的数字,并保留全部十进制精度。Jackson 注册 `JavaTimeModule` 
2.22.1。正确性检查比较数组内容和完整的 `OffsetDateTime` 值,允许时间戳在小数秒末尾零的数量上存在差异,只要它们表示相同的值。
+
+#### Users {#users}
+
+![Kotlin Users String 
序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/users_string_throughput.png)
+
+![Kotlin Users UTF-8 
字节序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/users_utf8_bytes_throughput.png)
+
+| 表示形式 | 操作 | Fory JSON Kotlin ops/s | kotlinx.serialization ops/s | Moshi 
ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | 序列化 | 3,132 | 520 | 625 | 1,128 |
+| String | 反序列化 | 1,782 | 509 | 443 | 371 |
+| UTF-8 字节 | 序列化 | 3,536 | 384 | 639 | 1,003 |
+| UTF-8 字节 | 反序列化 | 2,046 | 480 | 590 | 396 |
+
+在 Users 测试中,Fory 的 UTF-8 序列化吞吐量分别为 kotlinx.serialization 的 9.21 倍、Moshi 的 5.53 
倍和 Jackson Kotlin 的 3.52 倍。Fory 在两项反序列化操作中也取得最高吞吐量,这些操作包含嵌套记录与集合的构造工作。
+
+#### Clients {#clients}
+
+![Kotlin Clients String 
序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/clients_string_throughput.png)
+
+![Kotlin Clients UTF-8 
字节序列化与反序列化吞吐量](/img/blog/fory-kotlin-json/clients_utf8_bytes_throughput.png)
+
+| 表示形式 | 操作 | Fory JSON Kotlin ops/s | kotlinx.serialization ops/s | Moshi 
ops/s | Jackson Kotlin ops/s |
+| --- | --- | ---: | ---: | ---: | ---: |
+| String | 序列化 | 2,393 | 549 | 496 | 724 |
+| String | 反序列化 | 1,955 | 258 | 217 | 200 |
+| UTF-8 字节 | 序列化 | 3,947 | 418 | 499 | 621 |
+| UTF-8 字节 | 反序列化 | 2,070 | 256 | 253 | 215 |
+
+在 Clients 的 String 反序列化测试中,Fory 的吞吐量分别为 **kotlinx.serialization 的 7.59 倍、Moshi 
的 8.99 倍和 Jackson Kotlin 的 9.75 倍**。这些测量将比较范围扩展到同时包含 JDK 值类型、数组、文本和集合的模型。Users 
和 Clients 的全部 32 个测试用例均已完成,共产生 160 个测量样本。
+
+### 结果解读 {#interpreting-the-results}
+
+在每种负载的四项操作中,Fory 相对于其他库的吞吐量倍数分布如下。倍数根据未经四舍五入的原始分数计算:
+
+| Kotlin 模型 | 相对 kotlinx.serialization | 相对 Moshi | 相对 Jackson Kotlin |
+| --- | ---: | ---: | ---: |
+| MediaContent | 3.63×–11.62× | 6.35×–12.12× | 3.91×–8.37× |
+| Users | 3.50×–9.21× | 3.47×–5.53× | 2.78×–5.16× |
+| Clients | 4.36×–9.45× | 4.83×–8.99× | 3.31×–9.75× |
+
+在 1000 KB Kotlin 测试中,Fory 的吞吐量为对比库的 **2.78–9.75 倍**。这些结果对应所选模型和配置;测试负载并未测量值类和 
sealed 层次结构的性能。
+
+Users 和 Clients 
数据集沿用上游的字段长度、数值范围和集合大小,但采用自身的确定性生成序列。其[输入哈希与环境记录](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/results/users-clients/environment.json)标识了实际测试的文档。较小的
 MediaContent 
测试另有独立的[环境记录](https://github.com/chaokunyang/kotlin-json-benchmarks/blob/71399f45a9e6a55c07e127d240019ca9198446db/results/environment.json)。
+
+### Java 基准测试背景 {#java-benchmark-context}
+
+共用引擎也有已发布的 Java 测量结果。下表汇总了各负载已报告操作中,Fory JSON 相对于 Jackson 和 Gson 的吞吐量倍数:
+
+| Java 负载 | 相对 Jackson | 相对 Gson |
+| --- | ---: | ---: |
+| [MediaContent:String 和 UTF-8](/docs/benchmarks/json/java/) | 2.43×–5.55× | 
3.21×–10.00× |
+| [Users:1000 
KB](https://github.com/fabienrenaud/java-json-benchmark/pull/129) | 3.54×–5.33× 
| 5.65×–7.09× |
+| [Clients:1000 
KB](https://github.com/fabienrenaud/java-json-benchmark/pull/129) | 
6.97×–10.91× | 9.16×–10.89× |
+
+这些 Java 测试独立运行,采用不同的库版本和测量配置。Java 大文档报告使用 Fory JSON 1.6.0;Java MediaContent 
报告中,Gson 的字节测量包含其必需的 String 转换。链接中的报告保留了完整分数和配置。这些结果用于补充说明共用引擎的性能背景,不能作为 Kotlin 
与 Java 的性能比较。
+
+## JVM 与部署支持 {#jvm-and-deployment-support}
+
+该模块面向 Kotlin/JVM,无需依赖 `kotlin-reflect`。运行时使用 Kotlin 2.3.20 构建,接受 Kotlin 
严格元数据读取器所支持的模型元数据。[入门指南](/docs/json/getting-started)介绍了运行时配置,包括在 JDK 25 
及更高版本上建议开放的 `java.lang.invoke` 包。
+
+在 Android API 26 及更高版本上,Fory 使用解释执行的 JSON 映射。启用 R8 或 ProGuard 时,应添加 
`fory-json-kotlin-ksp`,并为所需的源码模型标注 `JsonType`,以保留映射所需的信息。GraalVM Native Image 
采用 `ForyJsonProvider` 流程:安装 Kotlin 模块,并选择可达模型进行代码生成。[Kotlin 
平台指南](/docs/json/kotlin#graalvm-and-android)提供了这两种环境的配置方式。Kotlin/Native、Kotlin/JS
 和 Kotlin/Wasm 不在此模块的支持范围内。
+
+## 进一步了解 {#learn-more}
+
+Fory JSON 让 Kotlin 应用在交换标准 JSON 的同时,保留模型声明的语义。构造函数默认值、可空性、值类身份和 sealed 
变体都参与映射,同一个可复用运行时提供 String API 和 UTF-8 API。
+
+[Kotlin JSON 
指南](/docs/json/kotlin)提供了完整的映射与平台参考。应用需要特定表示方式时,请参阅[自定义编解码器](/docs/json/custom-codecs);输入限制与类型控制见[安全指南](/docs/json/security)。源码和贡献说明位于
 [apache/fory](https://github.com/apache/fory)。
diff --git a/static/img/blog/fory-kotlin-json/clients_string_throughput.png 
b/static/img/blog/fory-kotlin-json/clients_string_throughput.png
new file mode 100644
index 00000000000..38e28ba797d
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/clients_string_throughput.png differ
diff --git a/static/img/blog/fory-kotlin-json/clients_utf8_bytes_throughput.png 
b/static/img/blog/fory-kotlin-json/clients_utf8_bytes_throughput.png
new file mode 100644
index 00000000000..928e96fbfc2
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/clients_utf8_bytes_throughput.png differ
diff --git a/static/img/blog/fory-kotlin-json/string_throughput.png 
b/static/img/blog/fory-kotlin-json/string_throughput.png
new file mode 100644
index 00000000000..f5666228df0
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/string_throughput.png differ
diff --git a/static/img/blog/fory-kotlin-json/users_string_throughput.png 
b/static/img/blog/fory-kotlin-json/users_string_throughput.png
new file mode 100644
index 00000000000..f5dc9355076
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/users_string_throughput.png differ
diff --git a/static/img/blog/fory-kotlin-json/users_utf8_bytes_throughput.png 
b/static/img/blog/fory-kotlin-json/users_utf8_bytes_throughput.png
new file mode 100644
index 00000000000..3f258e71614
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/users_utf8_bytes_throughput.png differ
diff --git a/static/img/blog/fory-kotlin-json/utf8_bytes_throughput.png 
b/static/img/blog/fory-kotlin-json/utf8_bytes_throughput.png
new file mode 100644
index 00000000000..0a6f0496a5b
Binary files /dev/null and 
b/static/img/blog/fory-kotlin-json/utf8_bytes_throughput.png differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to