import{_ as o,r as p,o as c,c as r,b as a,d as s,e as n,a as l}from"./app-OEUYI7Bq.js";const t={},i=l(`<h1 id="kavaref-extension" tabindex="-1"><a class="header-anchor" href="#kavaref-extension" aria-hidden="true">#</a> kavaref-extension</h1><p><img src="https://img.shields.io/maven-central/v/com.highcapable.kavaref/kavaref-extension?logo=apachemaven&amp;logoColor=orange&amp;style=flat-square" alt="Maven Central"><span style="margin-left:5px;"></span><img src="https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Fraw.githubusercontent.com%2FHighCapable%2Fmaven-repository%2Frefs%2Fheads%2Fmain%2Frepository%2Freleases%2Fcom%2Fhighcapable%2Fkavaref%2Fkavaref-extension%2Fmaven-metadata.xml&amp;logo=apachemaven&amp;logoColor=orange&amp;label=highcapable-maven-releases&amp;style=flat-square" alt="Maven metadata URL"></p><p>这是 KavaRef 相关功能的扩展依赖。</p><h2 id="配置依赖" tabindex="-1"><a class="header-anchor" href="#配置依赖" aria-hidden="true">#</a> 配置依赖</h2><p>你可以使用如下方式将此模块添加到你的项目中。</p><h3 id="version-catalog-推荐" tabindex="-1"><a class="header-anchor" href="#version-catalog-推荐" aria-hidden="true">#</a> Version Catalog (推荐)</h3><p>在你的项目 <code>gradle/libs.versions.toml</code> 中添加依赖。</p><div class="language-toml line-numbers-mode" data-ext="toml"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">[</span><span style="color:#F69D50;">versions</span><span style="color:#ADBAC7;">]</span></span>
<span class="line"><span style="color:#ADBAC7;">kavaref-extension = </span><span style="color:#96D0FF;">&quot;&lt;version&gt;&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ADBAC7;">[</span><span style="color:#F69D50;">libraries</span><span style="color:#ADBAC7;">]</span></span>
<span class="line"><span style="color:#ADBAC7;">kavaref-extension = { module = </span><span style="color:#96D0FF;">&quot;com.highcapable.kavaref:kavaref-extension&quot;</span><span style="color:#ADBAC7;">, version.ref = </span><span style="color:#96D0FF;">&quot;kavaref-extension&quot;</span><span style="color:#ADBAC7;"> }</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在你的项目 <code>build.gradle.kts</code> 中配置依赖。</p><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">implementation</span><span style="color:#ADBAC7;">(libs.kavaref.extension)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>请将 <code>&lt;version&gt;</code> 修改为此文档顶部显示的版本。</p><h3 id="传统方式" tabindex="-1"><a class="header-anchor" href="#传统方式" aria-hidden="true">#</a> 传统方式</h3><p>在你的项目 <code>build.gradle.kts</code> 中配置依赖。</p><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#DCBDFB;">implementation</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.highcapable.kavaref:kavaref-extension:&lt;version&gt;&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>请将 <code>&lt;version&gt;</code> 修改为此文档顶部显示的版本。</p><h2 id="功能介绍" tabindex="-1"><a class="header-anchor" href="#功能介绍" aria-hidden="true">#</a> 功能介绍</h2>`,16),d={href:"https://highcapable.github.io/KavaRef/KDoc/kavaref-extension",target:"_blank",rel:"noopener noreferrer"},y=l(`<h3 id="class-扩展" tabindex="-1"><a class="header-anchor" href="#class-扩展" aria-hidden="true">#</a> Class 扩展</h3><p>KavaRef 提供了一些扩展，在处理 <code>Class</code> 对象时会更加方便。</p><p>KavaRef 对 <code>Class</code> 的扩展同样添加了 <code>KClass</code> 扩展，作用是调用 <code>KClass.java</code>，写法上比直接使用 <code>Some::class.java</code> 更加简洁。</p><h4 id="创建-class-对象" tabindex="-1"><a class="header-anchor" href="#创建-class-对象" aria-hidden="true">#</a> 创建 Class 对象</h4><p>例如我们需要使用字符串类名创建一个 <code>Class</code> 对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 你可以使用带有 OrNull 后缀的方法在找不到 Class 时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toClassOrNull</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这些方法统一使用 <code>ClassLoaderProvider</code> 来获取默认的 <code>ClassLoader</code>，你可以设置默认的 <code>ClassLoader</code> 以影响全局功能。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#ADBAC7;">ClassLoaderProvider.classLoader </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MyCustomClassLoader</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>你也可以手动向 <code>toClass</code> 方法传入一个 <code>ClassLoader</code> 参数来指定使用哪个 <code>ClassLoader</code>。</p><h4 id="class-对象引用" tabindex="-1"><a class="header-anchor" href="#class-对象引用" aria-hidden="true">#</a> Class 对象引用</h4><p>在 Kotlin 中引用 Java Class 需要写很长的声明，例如 <code>MyClass::class.java</code>，此时你可以用以下方式来简化。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">classOf</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">MyClass</span><span style="color:#ADBAC7;">&gt;()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>你可以使用 <code>isSubclassOf</code> 方法来判断一个 <code>Class</code> 是否是另一个 <code>Class</code> 的子类。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> isSubclass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;"> isSubclassOf MySuperClass::</span><span style="color:#DCBDFB;">class</span></span>
<span class="line"><span style="color:#768390;">// 当然，它也有一个对应的反义判断方法</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> isNotSubclass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;"> isNotSubclassOf MySuperClass::</span><span style="color:#DCBDFB;">class</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以使用 <code>hasSuperclass</code> 和 <code>hasInterfaces</code> 方法来判断一个 <code>Class</code> 是否有超类或接口。</p><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p><code>classOf</code> 方法传入的 <code>Class</code> 默认会进行 Java 包装类的拆箱操作，无论你传入的是类似 <code>kotlin.Boolean</code> 还是 <code>java.lang.Boolean</code> (参考下方的 <a href="#java-%E5%8C%85%E8%A3%85%E7%B1%BB%E6%89%A9%E5%B1%95">Java 包装类扩展</a>)， 如果你需要避免传入的 <code>Class</code> 被拆箱变为原始类型，你需要明确设置 <code>primitiveType = false</code> 参数。</p></div><h4 id="创建新的实例" tabindex="-1"><a class="header-anchor" href="#创建新的实例" aria-hidden="true">#</a> 创建新的实例</h4><p>KavaRef 为 <code>Class</code> 提供了一个方法来方便地创建一个新的实例，你不需要考虑构造参数的类型，你只需要传入对应的参数即可立即创建一个新的实例。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">createInstance</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Hello&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">123</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 你也可以使用带有 OrNull 后缀的方法在创建失败时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">createInstanceOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Hello&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">123</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// createInstance 方法默认仅过滤公开的构造方法，如果你需要调用非公有构造方法，请设置 isPublic = false</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassWithPrivateConstructor </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">createInstance</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;Private!&quot;</span><span style="color:#ADBAC7;">, isPublic </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 如果你想指定创建实例的类型使用另一个类型，可以使用以下方法</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> mySuperClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClas::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">createInstanceAsType</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">MySuperClass</span><span style="color:#ADBAC7;">&gt;(</span><span style="color:#96D0FF;">&quot;Hello&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">123</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 同样地，你也可以使用带有 OrNull 后缀的方法在创建失败时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> mySuperClassOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">createInstanceAsTypeOrNull</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">MySuperClass</span><span style="color:#ADBAC7;">&gt;(</span><span style="color:#96D0FF;">&quot;Hello&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#6CB6FF;">123</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">小提示</p><p><code>createInstance</code> 方法在成功匹配一次后，会将结果进行缓存防止重复反射造成的性能损耗，它是线程安全的，你可以放心在任何标准场景下使用。</p></div><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>当你传入带有 <code>null</code> 的参数时，KavaRef 会尝试将其作为可匹配到条件的一部分 (模糊条件)，准确性可能会下降。</p><p><code>createInstance</code> 方法不允许所有参数均为 <code>null</code> 的情况 (条件完全模糊)，会直接抛出异常，因为这种情况无法确定要创建哪个实例。</p></div><h4 id="class-修饰符" tabindex="-1"><a class="header-anchor" href="#class-修饰符" aria-hidden="true">#</a> Class 修饰符</h4><p>KavaRef 也对 <code>Modifier</code> 进行了扩展，你可以直接使用 <code>Class.isPublic</code> 等方法来判断一个 <code>Class</code> 的修饰符。</p><h4 id="variousclass" tabindex="-1"><a class="header-anchor" href="#variousclass" aria-hidden="true">#</a> VariousClass</h4><p>KavaRef 提供了 <code>VariousClass</code> 类来装载不确定完整类名的 <code>Class</code> 对象，并返回成功匹配到的第一个。</p><p>此功能通常可用于 Android 应用中那些被 R8 混淆后的类名。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设在 A 版本中，这个类为 com.example.a，</span></span>
<span class="line"><span style="color:#768390;">// 在 B 版本中，这个类为 com.example.b</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.a&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.example.b&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">load</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 你也可以使用后缀名为 OrNull 的方法在找不到 Class 时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.a&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.example.b&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">loadOrNull</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="延迟装载-class-对象" tabindex="-1"><a class="header-anchor" href="#延迟装载-class-对象" aria-hidden="true">#</a> 延迟装载 Class 对象</h4><p>KavaRef 提供了 <code>LazyClass</code> 类来延迟装载 <code>Class</code> 对象。</p><p>你可以在需要时再装载 <code>Class</code>，而不是在创建时就立即装载，这可以解决一些需要运行时或运行到特定条件下才需要装载的 <code>Class</code>。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 定义一个不可为空延迟装载的 Class 并托管给 myClass</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 定义一个可为空延迟装载的 Class 并托管给 myClassOrNull</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassOrNull </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClassOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 它亦可支持传入 VariousClass</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> otherClassOrNull </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazyClassOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#DCBDFB;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.a&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;com.example.b&quot;</span><span style="color:#ADBAC7;">))</span></span>
<span class="line"><span style="color:#768390;">// 在需要时调用即装载</span></span>
<span class="line"><span style="color:#ADBAC7;">myClass.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">myClassOrNull?.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#ADBAC7;">otherClassOrNull?.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="classloader-扩展" tabindex="-1"><a class="header-anchor" href="#classloader-扩展" aria-hidden="true">#</a> ClassLoader 扩展</h4><p>KavaRef 还为 <code>ClassLoader</code> 提供了一些实用的扩展方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这就是你的 ClassLoader</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> classLoader: </span><span style="color:#F69D50;">ClassLoader</span></span>
<span class="line"><span style="color:#768390;">// 装载一个 Class，在装载失败时返回 null</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> classLoader.</span><span style="color:#DCBDFB;">loadClassOrNull</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// 判断这个 Class 是否存在于当前 ClassLoader 中</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> isClassExists </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> classLoader.</span><span style="color:#DCBDFB;">hasClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;com.example.MyClass&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="数组-class-扩展" tabindex="-1"><a class="header-anchor" href="#数组-class-扩展" aria-hidden="true">#</a> 数组 Class 扩展</h3><p>在 Java 中，数组的 <code>Class</code> 对象是一个特殊的 <code>Class</code> 对象，通常，我们创建它的方式如下。</p><p>例如创建一个 <code>java.lang.String[]</code> 的 <code>Class</code> 对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> arrayClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> java.lang.reflect.Array.</span><span style="color:#DCBDFB;">newInstance</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java, </span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">).javaClass</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>这样写起来非常长，而且不方便维护，所以 KavaRef 提供了一个方法来简化这个过程。</p><p>现在，创建 <code>java.lang.String[]</code> 的 <code>Class</code> 对象可以这样写。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> arrayClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">ArrayClass</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="member-扩展" tabindex="-1"><a class="header-anchor" href="#member-扩展" aria-hidden="true">#</a> Member 扩展</h3><p>KavaRef 提供了一些扩展方法来简化对 <code>Member</code> 的操作。</p><p>你可以在任何 <code>Member</code> 对象上使用 <code>makeAccessible</code> 方法来设置其可访问性。</p><p>如果 <code>Member</code> 是 <code>AccessibleObject</code> 类型即可生效。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#768390;">// 假设这个是你当前的 Member 对象</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> method: </span><span style="color:#F69D50;">Method</span></span>
<span class="line"><span style="color:#768390;">// 设置方法可访问</span></span>
<span class="line"><span style="color:#ADBAC7;">method.</span><span style="color:#DCBDFB;">makeAccessible</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>同样地，KavaRef 也对 <code>Modifier</code> 进行了扩展，你可以直接使用 <code>Member.isPublic</code> 等方法来判断一个 <code>Member</code> 的修饰符。</p><h3 id="type-扩展" tabindex="-1"><a class="header-anchor" href="#type-扩展" aria-hidden="true">#</a> Type 扩展</h3><p>在 Java 中操作类型或泛型类型时，通常需要使用 <code>Type</code> 接口及其子接口来处理。</p><p>KavaRef 提供了一些扩展方法来简化对 <code>Type</code> 的操作。</p><p>例如，你可以将一个符合要求的 <code>Type</code> 转换为 <code>Class</code> 对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> type: </span><span style="color:#F69D50;">Type</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> clazz </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> type.</span><span style="color:#DCBDFB;">toClass</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 你也可以使用后缀名为 OrNull 的方法在转换失败时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> clazzOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> type.</span><span style="color:#DCBDFB;">toClassOrNull</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以将符合要求的 <code>Type</code> 转换为 <code>ParameterizedType</code> 对象。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> type: </span><span style="color:#F69D50;">Type</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> parameterizedType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> type.</span><span style="color:#DCBDFB;">asParameterizedType</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"><span style="color:#768390;">// 你也可以使用后缀名为 OrNull 的方法在转换失败时返回 null 而不是抛出异常</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> parameterizedTypeOrNull </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> type.</span><span style="color:#DCBDFB;">asParameterizedTypeOrNull</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你还可以使用以下方式获取超类中的泛型参数数组，这在一些超类与子类的封装操作中会经常用到。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass: </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;">&lt;*&gt;</span></span>
<span class="line"><span style="color:#768390;">// 获取 myClass 的超类的泛型参数数组，获取失败或无法获取时将返回空数组</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> arguments </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> myClass.</span><span style="color:#DCBDFB;">genericSuperclassTypeArguments</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="类型引用扩展" tabindex="-1"><a class="header-anchor" href="#类型引用扩展" aria-hidden="true">#</a> 类型引用扩展</h3><p>在 Java 中，方法的泛型会在编译后被类型擦除，在运行获取到的类型是 <code>java.lang.Object</code>。</p>`,72),u=a("code",null,"TypeRef",-1),v={href:"https://github.com/google/gson",target:"_blank",rel:"noopener noreferrer"},A=a("code",null,"TypeToken",-1),C=l(`<p>它的使用方法非常简单，你可以像下面这样使用它。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> listStringType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">typeRef</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">List</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;">&gt;&gt;()</span></span>
<span class="line"><span style="color:#768390;">// 获取存储的类型，将会是 List&lt;? extends String&gt;</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> listStringType.type</span></span>
<span class="line"><span style="color:#768390;">// 获取其原始类型，将会是 List</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> rawType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> listStringType.rawType</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在使用 Gson 等需要传入 <code>Type</code> 的场景中，你可以为此实现一个带有 <code>reified</code> 泛型的扩展方法。</p><blockquote><p>示例如下</p></blockquote><div class="language-kotlin line-numbers-mode" data-ext="kt"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> gson </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Gson</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F47067;">inline</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> &lt;</span><span style="color:#F69D50;">reified</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;"> : </span><span style="color:#F69D50;">Any</span><span style="color:#ADBAC7;">&gt; </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toJson</span><span style="color:#ADBAC7;">(): </span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> gson.</span><span style="color:#DCBDFB;">toJson</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">this</span><span style="color:#ADBAC7;">, </span><span style="color:#DCBDFB;">typeRef</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">&gt;().type)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#768390;">// 使用方法</span></span>
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> json </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">listOf</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">&quot;KavaRef&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;is&quot;</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">&quot;awesome&quot;</span><span style="color:#ADBAC7;">).</span><span style="color:#DCBDFB;">toJson</span><span style="color:#ADBAC7;">()</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="java-包装类扩展" tabindex="-1"><a class="header-anchor" href="#java-包装类扩展" aria-hidden="true">#</a> Java 包装类扩展</h3><p>在 Kotlin 中直接使用 <code>Boolean::class</code>、<code>Byte::class</code> 等方式获取到的是 Java 的原始类型 <code>boolean</code>、<code>byte</code> 而不是它们的包装类。</p><p>如果你需要获取 Java 的包装类，你需要使用完整的 <code>java.lang.Boolean::class</code>、<code>java.lang.Byte::class</code> 等方式或使用 <code>Boolean::class.javaObjectType</code>、<code>Byte::class.javaObjectType</code>。</p><p>所以，KavaRef 提供了一些类型别名来处理 Java 的包装类，现在你只需要在这些类型加上 <code>J</code> 前缀即可，例如 <code>JBoolean::class</code>， 它等价于 <code>java.lang.Boolean::class</code>，部分类型需要填写全称，例如 <code>JInteger::class</code>。</p>`,10);function D(m,B){const e=p("ExternalLinkIcon");return c(),r("div",null,[i,a("p",null,[s("你可以 "),a("a",d,[s("点击这里"),n(e)]),s(" 查看 KDoc。")]),y,a("p",null,[s("KavaRef 提供了 "),u,s(" 类来包装你的目标泛型来确保你可以在运行时获取到正确的泛型类型，它的核心功能参考于 "),a("a",v,[s("Gson"),n(e)]),s(" 的 "),A,s("。")]),C])}const h=o(t,[["render",D],["__file","kavaref-extension.html.vue"]]);export{h as default};
