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 86a79488d6 🔄 synced local 'docs/guide/' with remote 'docs/guide/'
86a79488d6 is described below

commit 86a79488d608249553782640983520a810b2ef7d
Author: chaokunyang <[email protected]>
AuthorDate: Wed Jul 15 14:07:25 2026 +0000

    🔄 synced local 'docs/guide/' with remote 'docs/guide/'
---
 docs/guide/java/android-support.md |  90 +++++------
 docs/guide/java/graalvm-support.md |  21 ++-
 docs/guide/java/json-support.md    | 304 ++++++++++++++-----------------------
 3 files changed, 170 insertions(+), 245 deletions(-)

diff --git a/docs/guide/java/android-support.md 
b/docs/guide/java/android-support.md
index 5d119ad770..f1854f8cca 100644
--- a/docs/guide/java/android-support.md
+++ b/docs/guide/java/android-support.md
@@ -48,88 +48,78 @@ Fory JSON supports ordinary classes on Android API level 26 
and later through th
 `fory-json` artifact. Runtime JSON code generation and asynchronous 
compilation are disabled
 automatically, so `ForyJson.builder().build()` uses the interpreted object 
mapper.
 
-Add Fory JSON to the application and put the annotation processor on the 
module's processor path:
+Add Fory JSON to the application:
 
 ```kotlin
 dependencies {
   implementation("org.apache.fory:fory-json:${foryVersion}")
-  
annotationProcessor("org.apache.fory:fory-annotation-processor:${foryVersion}")
 }
 ```
 
-`@JsonType` is optional. Add it to application models when the processor 
should emit exact R8 rules
-and metadata for `@JsonCodec` type uses, including qualified roots, parameter 
types, generic
-arguments, and array components:
+`@JsonCodec` has the same declaration behavior on Android and the JVM. It 
supports complete values,
+direct collection and array elements, `Optional` and `AtomicReference` 
contents, Map keys and
+values, ordinary getters, setter value parameters, and `JsonCreator` 
parameters:
 
 ```java
 import java.util.List;
 import org.apache.fory.json.annotation.JsonCodec;
-import org.apache.fory.json.annotation.JsonType;
 
-@JsonType
-public final class GeneratedInvoice {
-  public List<@JsonCodec(MoneyCodec.class) Money> items;
+public final class Invoice {
+  @JsonCodec(elementCodec = MoneyCodec.class)
+  public List<Money> items;
+  private Money primary;
 
-  public GeneratedInvoice() {}
+  public void setPrimary(@JsonCodec(MoneyCodec.class) Money primary) {
+    this.primary = primary;
+  }
+
+  public Invoice() {}
 }
 ```
 
-Without `@JsonType`, ordinary reflection mapping and `@JsonCodec` declarations 
on types, fields, and
-effective ordinary getters still work. A release-minified application must 
supply equivalent exact
-R8 rules for every reflected class, constructor, field, method, generic 
signature, and runtime
-annotation. For example:
-
-```java
-public final class ManualInvoice {
-  @JsonCodec(MoneyCodec.class)
-  public Money total;
+Child codecs act on one direct level only. For example, `elementCodec` on 
`Money[][]` handles each
+`Money[]`, and `elementCodec` on `AtomicReferenceArray<Money>` handles each 
`Money`. Use a complete
+`value` codec when deeper custom behavior is required.
 
-  public ManualInvoice() {}
-}
-```
+`@JsonType` is optional. Add the annotation processor and mark application 
models with `JsonType`
+when the build should generate exact R8 rules:
 
-```proguard
--keepattributes 
Signature,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeVisibleTypeAnnotations,AnnotationDefault,MethodParameters
--keep,allowoptimization class com.example.ManualInvoice {
-  public <init>();
-  public com.example.Money total;
-}
--keep,allowoptimization,allowobfuscation class com.example.MoneyCodec {
-  public <init>();
+```kotlin
+dependencies {
+  
annotationProcessor("org.apache.fory:fory-annotation-processor:${foryVersion}")
 }
 ```
 
-Application-authored rules cannot supply codec type-use metadata that Android 
reflection does not
-expose. For example, this nested annotation is not applied on Android when the 
class omits
-`@JsonType`, even if exact rules retain the class, field, generic signature, 
and type annotation:
-
 ```java
-public final class UnsupportedNestedInvoice {
-  public List<@JsonCodec(MoneyCodec.class) Money> items;
+import org.apache.fory.json.annotation.JsonType;
 
-  public UnsupportedNestedInvoice() {}
+@JsonType
+public final class Invoice {
+  // ...
 }
 ```
 
+Applications that omit `JsonType` can supply equivalent exact rules 
themselves. Retain every model
+constructor, field, method, generic signature, declaration annotation, and 
parameter annotation used
+by Fory JSON, plus the public no-argument constructor of every 
annotation-selected codec. For the
+previous `Invoice` example:
+
 ```proguard
--keepattributes Signature,RuntimeVisibleTypeAnnotations
--keep,allowoptimization class com.example.UnsupportedNestedInvoice {
+-keepattributes 
Signature,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations
+-keepattributes AnnotationDefault,MethodParameters,InnerClasses,EnclosingMethod
+-keep,allowoptimization class com.example.Invoice {
   public <init>();
   public java.util.List items;
+  public void setPrimary(com.example.Money);
+}
+-keep,allowoptimization,allowobfuscation class com.example.MoneyCodec {
+  public <init>();
 }
 ```
 
-On Android, a pure type-use `@JsonCodec` requires `@JsonType`. This includes a 
qualified root type
-use, a parameter type, a generic argument, and an array component. Type 
declarations, field
-declarations, and effective ordinary getter declarations remain available 
through direct
-reflection without `@JsonType`.
-
-On the JVM and in a native image, a field or effective ordinary getter 
declaration takes precedence
-over a codec on the root annotated type. Android reads the declaration 
directly and obtains pure
-type-use facts from the generated companion. A setter, creator factory, 
unrelated method, or void
-method cannot declare `@JsonCodec`. `JsonAnyProperty` and `JsonAnyGetter` 
flatten their Map rather
-than exposing a complete root value, so their root declaration and root 
type-use codec forms are
-invalid; annotate the Map value type when a nested codec is needed.
+The same exact-rule approach supports every `JsonCodec` member; it is not 
limited to complete-value
+codecs. `JsonType` only automates rule generation on Android and is not 
required for codec
+selection.
 
 Android Fory JSON requires a retained no-argument constructor for an ordinary 
mutable class; it may
 be non-public when Android reflection can make it accessible. `JsonCreator` 
constructor-backed
diff --git a/docs/guide/java/graalvm-support.md 
b/docs/guide/java/graalvm-support.md
index 953a340316..7dda12f23e 100644
--- a/docs/guide/java/graalvm-support.md
+++ b/docs/guide/java/graalvm-support.md
@@ -84,14 +84,19 @@ other builder options retain their normal behavior. 
Applications can create diff
 `ForyJson` instances at runtime and do not need build-time initialization or 
reflection
 configuration.
 
-Type, field, effective ordinary getter, inherited, and nested type-use 
`@JsonCodec` annotations are
-supported. For a field or getter, the declaration is checked first and the 
root annotated type is
-used only when the declaration is absent. Nested generic arguments and array 
components remain
-fully supported in a native image.
-
-`JsonAnyProperty` and `JsonAnyGetter` flatten their Map and have no complete 
root value, so a field
-or method declaration codec and a root type-use codec are invalid there. A 
nested codec on the Map
-value remains supported.
+Type, field, effective ordinary getter, setter value parameter, and 
`JsonCreator` parameter
+`@JsonCodec` annotations are supported. The Feature registers every selected 
complete-value,
+element, content, Map-key, and Map-value codec constructor. This is the same 
annotation model used
+on the JVM and Android.
+
+`JsonAnyProperty` and `JsonAnyGetter` flatten their Map into the enclosing 
object. Use
+`@JsonCodec(valueCodec = ...)` on that field or getter to customize each 
dynamic value. A second
+`JsonAnySetter` parameter may use the normal configuration for its own value 
shape.
+
+Child codecs act on one direct level. `elementCodec` supports `Collection`, 
Java arrays, and
+`AtomicReferenceArray`; `contentCodec` supports `Optional` and 
`AtomicReference`; `keyCodec` and
+`valueCodec` support Map keys and values. A complete `value` codec cannot be 
combined with a child
+codec.
 
 An annotation codec must have the same public no-argument constructor required 
on the JVM. In a
 named module, export or open its package to `org.apache.fory.json`. A codec 
instance supplied
diff --git a/docs/guide/java/json-support.md b/docs/guide/java/json-support.md
index ceef6137ab..8836e5ef9a 100644
--- a/docs/guide/java/json-support.md
+++ b/docs/guide/java/json-support.md
@@ -324,9 +324,9 @@ import org.apache.fory.json.annotation.JsonSubTypes;
 import org.apache.fory.json.annotation.JsonType;
 ```
 
-`JsonType` marks a reachable object model for GraalVM Native Image metadata. 
On Android it also
-enables processor-generated R8 rules and `JsonCodec` type-use metadata. It has 
no effect on ordinary
-JVM JSON behavior and is not inherited. See [GraalVM 
Support](graalvm-support.md) and
+`JsonType` marks a reachable object model for GraalVM Native Image metadata. 
On Android it enables
+processor-generated R8 rules. It has no effect on ordinary JVM JSON behavior 
and is not inherited.
+See [GraalVM Support](graalvm-support.md) and
 [Android Support](android-support.md) for the platform workflows.
 
 ### `JsonProperty`
@@ -720,10 +720,10 @@ concurrently and must be thread-safe. A custom codec on a 
subtype is compatible
 inclusion, not inline property inclusion. A codec on the base replaces its 
`JsonSubTypes`
 annotation.
 
-### `JsonCodec` declarations and type uses
+### Selecting codecs with `JsonCodec`
 
-Use `@JsonCodec` on a class, record, enum, or interface to make a codec the 
default representation
-for that declaration and its descendants:
+Use `@JsonCodec` on a class, record, enum, or interface to declare its default 
complete-value
+codec. The positional form is shorthand for `value`:
 
 ```java
 @JsonCodec(MoneyCodec.class)
@@ -735,245 +735,175 @@ public interface Account {}
 public final class RetailAccount implements Account {}
 ```
 
-The default applies at root `Class` and raw `TypeRef` targets and at 
unannotated nested value
-positions. Fory explicitly inherits declarations through superclasses and 
interfaces; it does not
-use Java `@Inherited`.
+Type declarations are inherited through both superclasses and interfaces. The 
most-specific
+declaration wins. Unrelated declarations using the same codec are consistent; 
unrelated
+declarations using different codecs fail instead of depending on reflection 
order.
 
-On a field or effective ordinary getter, a declaration annotation selects the 
codec for that
-member's root value:
+On a field or effective ordinary getter, `value` replaces the complete 
property value. The same
+annotation is supported on an effective setter value parameter, a 
`JsonCreator` constructor or
+factory parameter, and a record component through Java's field, accessor, and 
constructor-parameter
+propagation:
 
 ```java
 public final class Invoice {
   @JsonCodec(MoneyCodec.class)
   public Money total;
+  private Money tax;
+  private Money discount;
 
   @JsonCodec(MoneyCodec.class)
   public Money getTax() {
     return tax;
   }
+
+  public void setDiscount(@JsonCodec(MoneyCodec.class) Money discount) {
+    this.discount = discount;
+  }
+
+  @JsonCreator
+  public Invoice(@JsonProperty("total") @JsonCodec(MoneyCodec.class) Money 
total) {
+    this.total = total;
+  }
 }
 ```
 
-The method form is invalid on record accessors, setters, creator factories, 
unrelated methods, and
-void methods. An ordinary getter declaration is invalid when field mode 
disables getter discovery.
-Existing record-component `@JsonCodec` behavior is unchanged; declaring 
`@JsonCodec` only on a
-record accessor is unsupported. For a selected field or getter, Fory checks 
the declaration first
-and uses the annotation on the root annotated type only when the declaration 
is absent.
-
-Use the same annotation at a type-use position to select a codec for exactly 
that occurrence:
+Use a child member when the standard container should remain in control and 
only its direct child
+needs a custom codec:
 
 ```java
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceArray;
 
-public final class Invoice {
-  // Qualified placement selects the root type-use fallback rather than the 
field declaration.
-  public com.example.@JsonCodec(MoneyCodec.class) Money qualifiedTotal;
+public final class InvoiceGroup {
+  @JsonCodec(elementCodec = MoneyCodec.class)
+  public List<Money> items;
 
-  public List<@JsonCodec(MoneyCodec.class) Money> items;
-  public Set<@JsonCodec(MoneyCodec.class) Money> uniqueItems;
-  public Collection<@JsonCodec(MoneyCodec.class) Money> allItems;
-  public Map<String, @JsonCodec(MoneyCodec.class) Money> byName;
-  public Optional<@JsonCodec(MoneyCodec.class) Money> optional;
-  public AtomicReference<@JsonCodec(MoneyCodec.class) Money> current;
+  @JsonCodec(elementCodec = MoneyCodec.class)
+  public Money[] itemArray;
 
-  // Codec for each element.
-  public com.example.@JsonCodec(MoneyCodec.class) Money[] itemArray;
+  @JsonCodec(elementCodec = MoneyCodec.class)
+  public AtomicReferenceArray<Money> atomicItems;
 
-  // Codec for the complete array value.
-  public Money @JsonCodec(MoneyArrayCodec.class) [] encodedArray;
+  @JsonCodec(contentCodec = MoneyCodec.class)
+  public Optional<Money> optional;
 
-  // Codec for each complete inner Set value.
-  public List<@JsonCodec(MoneySetCodec.class) Set<Money>> groups;
+  @JsonCodec(contentCodec = MoneyCodec.class)
+  public AtomicReference<Money> current;
 
-  // Normal containers with a codec only at the leaf.
-  public List<Set<@JsonCodec(MoneyCodec.class) Money>> nestedItems;
+  @JsonCodec(keyCodec = CurrencyKeyCodec.class, valueCodec = MoneyCodec.class)
+  public Map<Currency, Money> byCurrency;
 }
 ```
 
-Every array dimension is a distinct type-use node. This recursive model also 
covers
-multidimensional arrays, `AtomicReferenceArray`, concrete containers, and 
generic container
-subclasses. Fory follows the inherited `Collection<E>` or `Map<K,V>` binding 
instead of assuming a
-fixed type-argument index.
-
-One logical property's field, effective getter, effective setter, record 
component, and matching
-creator parameter contribute to one resolved codec tree. Missing annotations 
are not conflicts;
-equal codec classes at one node merge, while different classes fail with both 
sources and the
-nested path. Type-use metadata survives generic substitution, including a 
codec attached to a
-bound type argument used by a field declared as a type variable. Supported 
positions include field
-and record-component types, getter return types, setter value parameters, and 
`JsonCreator`
-constructor or factory value parameters.
-
-`TypeRef` preserves ordinary Java generic types but not arbitrary occurrence 
annotations. A root
-`TypeRef<List<@JsonCodec(...) Money>>` therefore cannot carry that local 
override. Put it on a
-discovered model property, declare a default on `Money`, or use exact builder 
registration.
-
-### Codec precedence
-
-Fory chooses the complete codec for each current resolved value node using 
this exact order. An
-invalid higher-priority source fails rather than falling back.
+The child members have these meanings:
 
-| Priority | Source                                  | Matching rule           
                                                                                
  |
-| -------: | --------------------------------------- | 
---------------------------------------------------------------------------------------------------------
 |
-|        1 | Current member or `TYPE_USE @JsonCodec` | Exact resolved 
occurrence after declaration-first acquisition, property merging, and generic 
substitution |
-|        2 | `registerCodec(Target.class, instance)` | Exact target `Class`; 
never inherited                                                                 
    |
-|        3 | Direct type `@JsonCodec` declaration    | Current class, record, 
enum, or interface                                                              
   |
-|        4 | Inherited type declaration              | Most-specific 
superclass/interface result                                                     
            |
-|        5 | Existing mapping                        | `JsonSubTypes`, 
built-in/container mapping, then default object mapping                         
          |
+| Member         | Supported current value                           | Direct 
child handled by the codec |
+| -------------- | ------------------------------------------------- | 
--------------------------------- |
+| `elementCodec` | `Collection<E>`, `E[]`, `AtomicReferenceArray<E>` | `E`     
                          |
+| `contentCodec` | `Optional<T>`, `AtomicReference<T>`               | `T`     
                          |
+| `keyCodec`     | `Map<K, V>`                                       | JSON 
member name for `K`          |
+| `valueCodec`   | `Map<K, V>`                                       | direct 
`V` value                  |
 
-For each field or getter, its declaration takes precedence only over that same 
member's root
-annotated type. The selected field, getter, setter, record component, and 
creator occurrences are
-then merged as one logical property; different codecs at the same node remain 
a conflict.
-
-Rows 1 through 4 replace the whole current value mapping. They may therefore 
replace a scalar,
-enum, container, object, or `JsonSubTypes` representation. A current 
occurrence, exact
-registration, or direct declaration also resolves any lower-priority inherited 
ambiguity.
-
-### Deterministic inheritance and conflicts
-
-For inherited declarations, Fory collects every annotated proper superclass 
and interface, then
-removes a candidate when another declaring type is its Java subtype. The 
remaining most-specific
-declarations resolve as follows:
-
-- one declaration wins;
-- unrelated declarations naming the same codec class are consistent;
-- unrelated declarations naming different codec classes conflict.
-
-This is independent of `implements` order and reflection order. A child 
interface declaration
-overrides its parent declaration, and a child class declaration overrides its 
parent:
+A custom Map-key codec converts between the declared key and a JSON member 
name:
 
 ```java
-@JsonCodec(ParentCodec.class)
-interface Parent {}
+import java.util.Locale;
+import org.apache.fory.json.codec.MapKeyCodec;
 
-@JsonCodec(ChildCodec.class)
-interface Child extends Parent {}
-
-final class Value implements Child {} // ChildCodec
-
-@JsonCodec(BaseCodec.class)
-class Base {}
+public final class CurrencyKeyCodec implements MapKeyCodec {
+  @Override
+  public String toName(Object key) {
+    return ((Currency) key).name().toLowerCase(Locale.ROOT);
+  }
 
-@JsonCodec(ValueCodec.class)
-final class Concrete extends Base {} // ValueCodec
+  @Override
+  public Object fromName(String name) {
+    return Currency.valueOf(name.toUpperCase(Locale.ROOT));
+  }
+}
 ```
 
-Unrelated interfaces using a common codec are valid; different codecs are 
ambiguous:
+Code that used the removed type-use form should move the codec to the owning 
declaration:
 
 ```java
-@JsonCodec(CommonCodec.class)
-interface A {}
-
-@JsonCodec(CommonCodec.class)
-interface B {}
-
-final class Consistent implements A, B {}
-
-@JsonCodec(ACodec.class)
-interface Left {}
+// Before
+List<@JsonCodec(MoneyCodec.class) Money> items;
 
-@JsonCodec(BCodec.class)
-interface Right {}
-
-final class Ambiguous implements Left, Right {} // Metadata error.
+// Now
+@JsonCodec(elementCodec = MoneyCodec.class)
+List<Money> items;
 ```
 
-Superclass/interface candidates follow the same subtype rule:
+Use `contentCodec` for an `Optional` or `AtomicReference`, `valueCodec` for a 
Map value, and
+`elementCodec` for an array or `AtomicReferenceArray` element.
 
-| Declaring-type relationship                     | Codec classes     | Result 
                                                   |
-| ----------------------------------------------- | ----------------- | 
--------------------------------------------------------- |
-| Superclass implements or inherits the interface | Same or different | 
Superclass declaration wins because it is more specific   |
-| Superclass and interface are unrelated          | Same              | Common 
codec is accepted                                  |
-| Superclass and interface are unrelated          | Different         | 
Conflict; class does not automatically override interface |
+`Iterable<E>` values that are not `Collection<E>` do not support 
`elementCodec`. Use `value` when a
+complete codec should own such a value.
 
-Disambiguate by annotating the concrete class, annotating only the current 
type use, or registering
-an exact codec instance:
+Child configuration is intentionally one level deep. For `List<List<Money>>`, 
`elementCodec`
+handles each complete `List<Money>`. For `Money[][]`, it handles each 
`Money[]`. To customize a
+deeper descendant, implement a codec for the complete current value and select 
it with `value`.
 
-```java
-@JsonCodec(ConcreteCodec.class)
-final class DeclaredValue implements Left, Right {}
+`value` is mutually exclusive with every child member because it already owns 
the complete current
+value. An empty annotation, an unsupported child member, or an outer complete 
codec combined with
+a child member fails during model construction. A configured direct child must 
resolve to a
+concrete type; raw containers, direct wildcards, and unresolved direct type 
variables are rejected.
 
-final class Holder {
-  public @JsonCodec(LocalCodec.class) Ambiguous value;
-}
+`JsonAnyProperty` and `JsonAnyGetter` flatten their Map into the enclosing 
object. Configure their
+dynamic values with `valueCodec`:
 
-ForyJson json =
-    ForyJson.builder()
-        .registerCodec(Ambiguous.class, new ConcreteCodec())
-        .build();
+```java
+@JsonAnyProperty
+@JsonCodec(valueCodec = MoneyCodec.class)
+public Map<String, Money> extra;
 ```
 
-Fory retains Jackson's useful idea of explicitly inheriting annotations 
through class and
-interface hierarchies, but rejects traversal-order first-wins behavior. Java 
subtype specificity
-and codec-class identity decide the result; incomparable different codecs 
produce an error instead
-of depending on hierarchy declaration order.
-
-### Nested composition and Map keys
+The first `JsonAnySetter` parameter is the String property name. Its second 
parameter may use
+`@JsonCodec(value = ...)` or another configuration valid for that parameter's 
own shape.
 
-A custom codec owns its complete current value and cannot delegate annotated 
children. An explicit
-nested type-use under an outer custom codec is therefore rejected as hidden 
configuration:
+### Codec precedence and repeated declarations
 
-```java
-// Invalid: LocalCodec cannot run because CustomListCodec owns the whole list.
-public @JsonCodec(CustomListCodec.class)
-    List<@JsonCodec(LocalCodec.class) Money> values;
-```
+Fory resolves each current value in this order:
 
-A child class's declaration codec is only a lazy default. The outer codec 
prevents child lookup,
-so that default is not a hidden explicit instruction and is valid:
+| Priority | Source                                    |
+| -------: | ----------------------------------------- |
+|        1 | Current property or parameter `JsonCodec` |
+|        2 | Exact `registerCodec` registration        |
+|        3 | Direct type `JsonCodec` declaration       |
+|        4 | Inherited type declaration                |
+|        5 | Built-in or default JSON mapping          |
 
-```java
-@JsonCodec(MoneyCodec.class)
-final class DeclaredMoney {}
-
-public @JsonCodec(CustomListCodec.class) List<DeclaredMoney> values;
-```
+One logical property may expose the annotation from its field, getter, setter 
parameter, creator
+parameter, or record propagation. Repeated configurations must be identical; 
Fory does not merge
+partial configurations from different declarations. An unannotated effective 
override suppresses
+an inherited method annotation.
 
-The hidden-explicit-descendant rule also applies when the outer complete codec 
comes from builder
-registration or a class/interface declaration. Without an outer custom codec, 
arrays, collections,
-map values, Optional, and atomic references resolve their annotated children 
normally.
+A child member replaces only that direct child. Unconfigured Map siblings 
continue through the
+normal precedence. If an exact registration or type declaration supplies a 
complete codec for the
+outer container, a property child member is unreachable and therefore rejected.
 
-Map keys are JSON object member names, not JSON values. An explicit 
`@JsonCodec` anywhere in a Map
-key subtree is rejected. Builder or declaration value codecs on the key's raw 
type are ignored in
-key position and still apply when that type is used as a value. 
`JsonAnyProperty` and
-`JsonAnyGetter` flatten their Map and cannot select a whole-value codec; only 
the nested Map value
-node can. A field or method declaration codec and a root type-use codec are 
therefore invalid on
-those two forms. A `JsonAnySetter` value parameter is already one flattened 
value and may carry a
-root type-use codec. Wildcards, wildcard bounds, and type variables still 
unresolved after
-substitution cannot select a codec. A type-use on an `extends` or `implements` 
clause is not a JSON
-value occurrence and is not used; annotate the type declaration instead. 
Annotation type
-declarations are not supported JSON model targets.
+Map keys are JSON object member names and use `MapKeyCodec`, not 
`JsonValueCodec`. A custom key
+codec class follows the same construction rules as a value codec. Null Map 
keys are rejected, and
+decoded keys must match the declared key type.
 
-### Construction, inherited results, and platform support
+### Codec construction and platform support
 
 An annotation codec class must be public, concrete, top-level or static 
nested, and have a public
-no-argument constructor. One successfully constructed instance is shared by 
all annotated sites
-and concurrent operations of the built `ForyJson`; it must be thread-safe. Use
-`registerCodec(Target.class, instance)` when the codec needs configuration.
-
-In a named Java module, export or open the codec's package to 
`org.apache.fory.json`. Fory does not
-bypass a closed module boundary and reports an actionable access error.
-
-When a parent or interface declaration supplies the codec for a more specific 
target, every reader
-result must be null or assignable to that target. A parent codec may return 
the requested child and
-succeed. Returning a plain parent while decoding the child fails with 
`ForyJsonException` that
-names the target type, codec class, declaring type, and actual returned type. 
The actual result,
-not the parent's `final` status or the codec's generic signature, determines 
validity.
-
-`@JsonCodec` is supported on ordinary JVMs and GraalVM native images, 
including member
-declarations, inherited type declarations, and nested type uses. Native models 
must follow the
-`JsonType` workflow described in [GraalVM Support](graalvm-support.md), which 
registers the
-annotation codec's public no-argument constructor.
-
-Android directly reads type, field, and effective getter declarations. Pure 
type-use locations,
-including qualified roots, parameters, generic arguments, and array 
components, require `JsonType`
-processor metadata. `JsonType` also supplies automatic R8 rules; applications 
that omit it can
-supply exact rules manually and use declaration syntax, but type-use codecs 
remain unavailable. See
-[Android Support](android-support.md).
+no-argument constructor. One instance is shared by all annotated sites and 
concurrent operations of
+the built `ForyJson`, so it must be thread-safe. Use 
`registerCodec(Target.class, instance)` when a
+complete-value codec needs configuration.
+
+In a named Java module, export or open the codec package to 
`org.apache.fory.json`. When an inherited
+type-declaration codec is used for a more specific target, every decoded value 
must be null or
+assignable to that target.
+
+The annotation has the same FIELD, METHOD, and PARAMETER behavior on the JVM, 
Android, and GraalVM
+Native Image. Android applications may use `JsonType` for generated exact R8 
rules or provide the
+equivalent rules themselves. GraalVM object models follow the `JsonType` 
workflow in
+[GraalVM Support](graalvm-support.md).
 
 ## Type validation and untrusted input
 


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

Reply via email to