mirror of
https://github.com/HighCapable/KavaRef.git
synced 2025-09-06 02:35:21 +08:00
369 lines
101 KiB
JavaScript
369 lines
101 KiB
JavaScript
import{_ as r,r as p,o as t,c as i,b as n,d as s,e as l,w as o,a}from"./app-mh6GuRj9.js";const d={},A=a(`<h1 id="kavaref-core" tabindex="-1"><a class="header-anchor" href="#kavaref-core" aria-hidden="true">#</a> kavaref-core</h1><p><img src="https://img.shields.io/maven-central/v/com.highcapable.kavaref/kavaref-core?logo=apachemaven&logoColor=orange&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-core%2Fmaven-metadata.xml&logo=apachemaven&logoColor=orange&label=highcapable-maven-releases&style=flat-square" alt="Maven metadata URL"></p><p>这是 KavaRef 的核心依赖,你需要引入此模块才能使用 KavaRef 的基本功能。</p><h2 id="配置依赖" tabindex="-1"><a class="header-anchor" href="#配置依赖" aria-hidden="true">#</a> 配置依赖</h2><p>你可以使用以下方式将此模块添加到你的项目中。</p><h3 id="sweetdependency-推荐" tabindex="-1"><a class="header-anchor" href="#sweetdependency-推荐" aria-hidden="true">#</a> SweetDependency (推荐)</h3><p>在你的项目 <code>SweetDependency</code> 配置文件中添加依赖。</p><div class="language-yaml line-numbers-mode" data-ext="yml"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#8DDB8C;">libraries</span><span style="color:#ADBAC7;">:</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">com.highcapable.kavaref</span><span style="color:#ADBAC7;">:</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">kavaref-core</span><span style="color:#ADBAC7;">:</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#8DDB8C;">version</span><span style="color:#ADBAC7;">: </span><span style="color:#96D0FF;">+</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>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;">(com.highcapable.kavaref.kavaref.core)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><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-core = </span><span style="color:#96D0FF;">"<version>"</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-core = { module = </span><span style="color:#96D0FF;">"com.highcapable.kavaref:kavaref-core"</span><span style="color:#ADBAC7;">, version.ref = </span><span style="color:#96D0FF;">"kavaref-core"</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.core)</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>请将 <code><version></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;">"com.highcapable.kavaref:kavaref-core:<version>"</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><version></code> 修改为此文档顶部显示的版本。</p><h2 id="功能介绍" tabindex="-1"><a class="header-anchor" href="#功能介绍" aria-hidden="true">#</a> 功能介绍</h2>`,21),y={href:"https://highcapable.github.io/KavaRef/KDoc/kavaref-core",target:"_blank",rel:"noopener noreferrer"},D=a(`<h3 id="基本用法" tabindex="-1"><a class="header-anchor" href="#基本用法" aria-hidden="true">#</a> 基本用法</h3><p>KavaRef 采用链式调用的设计方案,它对可用的 Java 反射 API (例如 <code>Class</code>) 创建了扩展方法,你只需要对这些内容调用 <code>resolve()</code>,即可进入 KavaRef 的世界。</p><p>关系图如下。</p><div class="language-text" data-ext="text"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#adbac7;">KavaRef</span></span>
|
||
<span class="line"><span style="color:#adbac7;">└── KClass/Class.resolve()</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ├── method()</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> ├── constructor()</span></span>
|
||
<span class="line"><span style="color:#adbac7;"> └── field()</span></span>
|
||
<span class="line"><span style="color:#adbac7;"></span></span></code></pre></div><p>接下来,我们将给出多个示例的 Java <code>Class</code>,后续都将基于它们进行基本的反射方案讲解。</p><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">package</span><span style="color:#ADBAC7;"> com.demo;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BaseTest</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">BaseTest</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doBaseTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre></div><div class="language-java" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">package</span><span style="color:#ADBAC7;"> com.demo;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">extends</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">BaseTest</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> TAG </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"Test"</span><span style="color:#ADBAC7;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">boolean</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">isTaskRunning</span><span style="color:#F69D50;"> </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>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">doTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">release</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">, Function<</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">String</span><span style="color:#ADBAC7;">> </span><span style="color:#F69D50;">task</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isFinish</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">stop</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">private</span><span style="color:#ADBAC7;"> String </span><span style="color:#DCBDFB;">getName</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre></div><div class="language-java line-numbers-mode" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Box</span><span style="color:#ADBAC7;"><</span><span style="color:#F47067;">T</span><span style="color:#ADBAC7;">> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">print</span><span style="color:#ADBAC7;">(T </span><span style="color:#F69D50;">item</span><span style="color:#ADBAC7;">, String </span><span style="color:#F69D50;">str</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><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><p>假设,我们想要得到 <code>Test</code> 的 <code>doTask</code> 方法并执行,在 KavaRef 中,你可以通过以下方式来实现。</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 通过实例化 Class 的方式对其进行反射</span></span>
|
||
<span class="line"><span style="color:#768390;">// 在 KavaRef 中,你无需将其转换为 \`java.lang.Class\`,</span></span>
|
||
<span class="line"><span style="color:#768390;">// 它会自动调用 KClass.java</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 创建 KavaRef 反射</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 创建 Method (方法) 条件</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置方法名</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置方法参数类型</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 条件执行后会返回匹配到的 List<MethodResolver> 实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 这里我们获取到过滤结果的第一个</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">first</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在 MethodResolver 上设置 Test 的实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 调用方法并传入参数</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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 class="line-number"></div><div class="line-number"></div></div></div><p>在以上写法中,我们通过 <code>Test::class.resolve()</code> 来获取当前 <code>Class</code> 的 KavaRef 反射实例, 然后通过 <code>method { ... }</code> 来创建一个方法过滤条件 <code>MethodCondition</code>,在其中设置方法名和参数类型,执行后返回 <code>List<MethodResolver></code> 实例, 接着我们通过 <code>first()</code> 来获取第一个匹配到的 <code>MethodResolver</code> 实例, 然后通过 <code>of(test)</code> 来设置当前 <code>Class</code> 的实例,最后通过 <code>invoke("task_name")</code> 来执行方法并传入参数。</p><p>在这其中,<code>MethodCondition</code> 继承自 <code>MemberCondition</code>,它允许你对 <code>Method</code> 进行条件筛选,其中包含了 Java 核心的反射 API 的条件镜像,你可以查看对应的注释来了解每个 API 的原生用法。</p><p>同样地,<code>MethodResolver</code> 继承自 <code>MemberResolver</code>,它允许你对过滤结果中的 <code>Method</code> 进行反射调用。</p><p>由于这里的反射需求是得到一个可用的方法结果,所以 <code>method { ... }.first()</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;">Test::</span><span style="color:#DCBDFB;">class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 直接使用 firstMethod 来获取第一个匹配到的 MethodResolver 实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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><p>由于我们现在可以拿到 <code>Test</code> 的实例,那么还有一种简化写法,你可以直接使用这个实例创建 KavaRef 反射。</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;">// 在这里,Test 的实例 test 会被传给 KavaRef 并获取 test::class.java</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">test.</span><span style="color:#DCBDFB;">asResolver</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 由于你设置了实例,所以这里不再需要 of(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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></div><p>接下来,我们需要得到 <code>isTaskRunning</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> isTaskRunning </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> test.</span><span style="color:#DCBDFB;">asResolver</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstField</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"isTaskRunning"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Boolean::</span><span style="color:#DCBDFB;">class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Boolean</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></div><p><code>Test</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;"> test </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstConstructor</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 对于零参构造方法,可以使用以下条件过滤</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 它等价于 parameterCount = 0</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParameters</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">create</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 创建一个新的 Test 实例</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><p>你也可以使用 <code>createAsType<T>()</code> 为实际对象 <code>Test</code> 指定其超类类型 <code>BaseTest</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;"> test </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstConstructor</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">emptyParameters</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">createAsType</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">BaseTest</span><span style="color:#ADBAC7;">>() </span><span style="color:#768390;">// 创建一个新的 BaseTest 实例</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><div class="custom-container tip"><p class="custom-container-title">小提示</p><p>除了 <code>firstMethod</code> 等方法外,你也可以使用 <code>lastMethod</code> 等方法来获取最后一个匹配到的 <code>MethodResolver</code> 实例,它等价于 <code>method { ... }.last()</code>。</p><p>在得到 <code>MemberResolver</code> 实例后,你可以使用 <code>self</code> 来获取当前 <code>MemberResolver</code> 的 <code>Member</code> 原始实例来对其进行一些你自己的操作。</p><p>在继承于 <code>InstanceAwareResolver</code> 的 <code>MemberResolver</code> 中 (例如 <code>MethodResolver</code> 和 <code>FieldResolver</code>),你都可以使用 <code>of(instance)</code> 来设置当前实例,如果反射得到的是静态 (static) 成员,你无需设置实例。</p></div><div class="custom-container warning"><p class="custom-container-title">注意</p><p><code>Any.resolve()</code> 方法已在 <code>1.0.1</code> 版本被弃用,因为它会污染命名空间 (例如 <code>File.resolve("/path/to/file")</code>),现在请使用 <code>Any.asResolver()</code> 来代替。</p></div>`,31),B={class:"custom-container danger"},v=a(`<p class="custom-container-title">特别注意</p><p>在继承于 <code>InstanceAwareResolver</code> 的 <code>MemberResolver</code> 中,<code>of(instance)</code> 的类型要求与当前反射的 <code>Class</code> 实例泛型类型相同, 除非不指定 <code>Class</code> 泛型类型,或将 <code>Class</code> 泛型类型设置为 <code>Any</code>。</p><p>如果 <code>of(instance)</code> 出现 <code>Required: Nothing?</code> 错误 (这通常由于 <code>Class</code> 通过 <code>Class.forName(...)</code> 或 <code>ClassLoader.loadClass(...)</code> 创建), 则是你的 <code>Class</code> 为 <code>Class<*></code> (Java 中是 <code>Class<?></code>),此时如果你不想指定类型,请设置或转换为 <code>Class<Any></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;"> Class.</span><span style="color:#DCBDFB;">forName</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.xxx.MyClass"</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">as</span><span style="color:#ADBAC7;"> Class</span><span style="color:#F47067;"><</span><span style="color:#ADBAC7;">Any</span><span style="color:#F47067;">></span></span>
|
||
<span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClassInstance: </span><span style="color:#F69D50;">Any</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;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(myClassInstance).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">..</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></div>`,5),C=a(`<h3 id="模糊条件" tabindex="-1"><a class="header-anchor" href="#模糊条件" aria-hidden="true">#</a> 模糊条件</h3><p>你会注意到 <code>Test</code> 中有一个 <code>release</code> 方法,但是它的方法参数很长,而且部分类型可能无法直接得到。</p><p>此时,你可以借助 <code>parameters(...)</code> 条件使用 <code>VagueType</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"release"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用 VagueType 来填充不想填写的类型,同时保证其它类型能够匹配</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">, VagueType, Boolean::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 得到这个方法</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 warning"><p class="custom-container-title">注意</p><p><code>VagueType</code> 只能在有多个参数的过滤条件时使用,它不可以在只能设置单个参数的过滤条件中使用,例如 <code>type</code>。</p><p>你可以使用 <code>VagueType</code>、<code>VagueType::class</code> 或 <code>VagueType::class.java</code> 来创建,它们都能被正确识别为模糊过滤条件。</p></div><h3 id="自由条件" tabindex="-1"><a class="header-anchor" href="#自由条件" aria-hidden="true">#</a> 自由条件</h3><p>在 <code>MemberCondition</code> 中,<code>name</code>、<code>type</code>、<code>parameterCount</code> 等条件都可以使用 Kotlin lambda 特性创建自由过滤条件。</p><p>假设我们要得到 <code>Test</code> 中的 <code>doTask</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用 lambda 来设置方法名</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置名称不区分大小写</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">equals</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"dotask"</span><span style="color:#ADBAC7;">, ignoreCase </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置参数类型</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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>KavaRef 支持添加泛型过滤条件,你可以使用 <code>TypeMatcher</code> 提供的相关功能来实现。</p><p>假设我们需要过滤 <code>Box<String></code> 中的 <code>print</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> box: </span><span style="color:#F69D50;">Box</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;">></span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">box.</span><span style="color:#DCBDFB;">asResolver</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"print"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置泛型参数条件</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">genericParametes</span><span style="color:#ADBAC7;">(</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 过滤泛型名称 "T"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">typeVar</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"T"</span><span style="color:#ADBAC7;">),</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 通过 Class 创建 TypeMatcher</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">toTypeMatcher</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> )</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"item"</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">"str"</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 class="line-number"></div><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>你会注意到 <code>Test</code> 继承于 <code>BaseTest</code>,现在我们想得到 <code>BaseTest</code> 的 <code>doBaseTask</code> 方法。</p><p>在不知道超类名称的情况下,我们只需要在过滤条件中加入 <code>superclass()</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doBaseTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 只需要添加这个条件</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">superclass</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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><p>这个时候我们就可以在超类中获取到这个方法了。</p><div class="custom-container tip"><p class="custom-container-title">小提示</p><p><code>superclass()</code> 一旦设置就会自动循环向后过滤全部继承的超类中是否有这个方法,直到过滤到目标没有超类 (继承关系为 <code>java.lang.Object</code>) 为止。</p></div><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>当前过滤的方法除非指定 <code>superclass()</code> 条件,否则只能过滤到当前 <code>Class</code> 的方法,这是 Java 反射 API 的默认行为, KavaRef 会调用 <code>Class.getDeclaredMethods()</code> 来获取当前 <code>Class</code> 的方法而不是 <code>Class.getMethods()</code>。</p></div><h3 id="更多条件" tabindex="-1"><a class="header-anchor" href="#更多条件" aria-hidden="true">#</a> 更多条件</h3><p>KavaRef 提供了一些过滤条件来辅助 Java 反射 API 的使用。</p><p>假设我们要得到 <code>Test</code> 中的静态变量 <code>TAG</code> 的内容。</p><p>为了体现过滤的条件包含静态描述符 (static),我们可以使用以下方式来实现。</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;"> tag </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstField</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"TAG"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> String::</span><span style="color:#DCBDFB;">class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 创建描述符过滤</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;">(Modifiers.STATIC)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 或者</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">modifiers</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.</span><span style="color:#DCBDFB;">contains</span><span style="color:#ADBAC7;">(Modifiers.STATIC)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;">>() </span><span style="color:#768390;">// 获取字段内容</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 class="line-number"></div></div></div><p>你还可以在 <code>type</code>、<code>parameters</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用字符串类型传入完整类名</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"java.lang.String"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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><h3 id="异常处理" tabindex="-1"><a class="header-anchor" href="#异常处理" aria-hidden="true">#</a> 异常处理</h3><p>在默认情况下,KavaRef 会在反射调用过程中找不到成员时抛出异常。</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;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doNonExistentMethod"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 这里会抛出 NoSuchMethodException</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>optional()</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;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置可选条件</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">optional</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doNonExistentMethod"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 返回空的 List<MethodResolver></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><p>KavaRef 会打印完整的异常内容以供调试,在使用 <code>optional()</code> 时,异常会以 WARN 级别的日志打印。</p><blockquote><p>示例如下</p></blockquote><div class="language-text" data-ext="text"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#adbac7;">No method found matching the condition for current class.</span></span>
|
||
<span class="line"><span style="color:#adbac7;">+------------------------------------------------+</span></span>
|
||
<span class="line"><span style="color:#adbac7;">| class com.demo |</span></span>
|
||
<span class="line"><span style="color:#adbac7;">+------------+-----------------------------------+</span></span>
|
||
<span class="line"><span style="color:#adbac7;">| name | doNonExistentMethod |</span></span>
|
||
<span class="line"><span style="color:#adbac7;">| parameters | [class java.lang.String, boolean] |</span></span>
|
||
<span class="line"><span style="color:#adbac7;">+------------+-----------------------------------+</span></span>
|
||
<span class="line"><span style="color:#adbac7;"></span></span></code></pre></div><p>如果你不希望 KavaRef 抛出或打印任何内容,你可以使用 <code>optional(silent = true)</code> 静默化处理,但是我们<strong>不建议这样做</strong>,这会掩盖问题,除非有必要这么做。</p><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>如果你设置了 <code>optional()</code>,那么请不要使用 <code>firstMethod</code>、<code>firstConstructor</code> 等方法来获取单个结果, 因为它们会在没有结果时抛出列表为空的异常,你可以使用后缀为 <code>OrNull</code> 的方法来获取单个结果。</p><p>但是这里需要注意一个事情,<strong>如果你没有设置 <code>optional()</code>,那么 <code>firstMethodOrNull</code> 等方法依然会在没有结果时抛出异常</strong>,这是预期行为,因为 <code>method { ... }</code> 才是过滤器的 “构建” 操作,异常在此处理,<code>firstMethodOrNull</code> 等方法只是一个封装,是对结果 <code>List</code> 是否为空的 Kotlin 自身标准库异常处理,不参与 KavaRef 过滤器的异常处理。</p><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:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置可选条件</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">optional</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethodOrNull</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doNonExistentMethod"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 返回 MethodResolver 或 null</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></div><h3 id="日志管理" tabindex="-1"><a class="header-anchor" href="#日志管理" aria-hidden="true">#</a> 日志管理</h3><p>KavaRef 提供了其自身的日志管理功能,你可以通过 <code>KavaRef.logLevel</code> 来设置日志级别。</p><p>你可以设置 <code>KavaRef.logLevel = KavaRefRuntime.LogLevel.DEBUG</code> 来启用 DEBUG 级别的日志使得 KavaRef 在过滤过程向控制台打印更为详细的分步过滤条件日志。</p><p>如果你想关闭 KavaRef 的全部日志打印,你可以设置 <code>KavaRef.logLevel = KavaRefRuntime.LogLevel.OFF</code>。</p><p>如果你有更高级的需求,你可以实现 <code>KavaRefRuntime.Logger</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;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">MyLogger</span><span style="color:#ADBAC7;"> : </span><span style="color:#F69D50;">KavaRefRuntime</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">Logger</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里可以指定日志打印的标签</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tag </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"MyLogger"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">debug</span><span style="color:#ADBAC7;">(msg: </span><span style="color:#F69D50;">Any</span><span style="color:#ADBAC7;">?, throwable: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">?) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里实现你的日志打印逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">info</span><span style="color:#ADBAC7;">(msg: </span><span style="color:#F69D50;">Any</span><span style="color:#ADBAC7;">?, throwable: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">?) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里实现你的日志打印逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">warn</span><span style="color:#ADBAC7;">(msg: </span><span style="color:#F69D50;">Any</span><span style="color:#ADBAC7;">?, throwable: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">?) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里实现你的日志打印逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">error</span><span style="color:#ADBAC7;">(msg: </span><span style="color:#F69D50;">Any</span><span style="color:#ADBAC7;">?, throwable: </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">?) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里实现你的日志打印逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><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 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 class="line-number"></div></div></div><p>然后,将其设置到 KavaRef 上即可。</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;">KavaRef.</span><span style="color:#DCBDFB;">setLogger</span><span style="color:#ADBAC7;">(</span><span style="color:#DCBDFB;">MyLogger</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="进阶用法" tabindex="-1"><a class="header-anchor" href="#进阶用法" aria-hidden="true">#</a> 进阶用法</h3><p>上述内容讲解的均为标准场景下的使用方法,如果你有更加细粒度的使用场景,你可以手动创建 KavaRef 的相关组件。</p><p>如果你不喜欢 Kotlin lambda 的写法,你可以手动创建链式调用。</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 条件开始</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"doTask"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">build</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 条件结束 (执行)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">first</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test) </span><span style="color:#768390;">// 设置实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 手动创建 MethodCondition</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> condition </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MethodCondition</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">>()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition.name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition.</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 应用条件到反射对象</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;">(condition)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test) </span><span style="color:#768390;">// 设置实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 手动创建 MethodCondition</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> condition </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MethodCondition</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">>()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition.name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition.</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 手动创建 MemberCondition.Configuration</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> configuration </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">createConfiguration</span><span style="color:#ADBAC7;">(</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> memberInstance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> test, </span><span style="color:#768390;">// 设置实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> processorResolver </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;">// 使用默认的解析器,可参考下方的 "自定义解析器"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> superclass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span><span style="color:#ADBAC7;">, </span><span style="color:#768390;">// 是否在超类中过滤</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> optional </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> MemberCondition.Configuration.Optional.NO </span><span style="color:#768390;">// 配置可选条件</span></span>
|
||
<span class="line"><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;"> resolvers </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> condition.</span><span style="color:#DCBDFB;">build</span><span style="color:#ADBAC7;">(configuration)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 获取第一个结果</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> resolver </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> resolvers.</span><span style="color:#DCBDFB;">first</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// 执行方法</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">resolver.</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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><p>如果你对业务层逻辑有更高级的需求,你还可以使用 <code>mergeWith</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 手动创建 MethodCondition</span></span>
|
||
<span class="line"><span style="color:#768390;">// 创建第一个条件</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> condition1 </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MethodCondition</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">>()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition1.name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#768390;">// 创建第二个条件</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> condition2 </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MethodCondition</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">>()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition2.</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 将 condition2 合并到 condition1 中</span></span>
|
||
<span class="line"><span style="color:#768390;">// 此时 condition1 的条件将包含 condition2 不为 null 的条件,</span></span>
|
||
<span class="line"><span style="color:#768390;">// condition1 中重复的条件将被 condition2 的条件覆盖</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition1.</span><span style="color:#DCBDFB;">mergeWith</span><span style="color:#ADBAC7;">(condition2)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 你还可以使用 infix 语法</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">condition1 mergeWith condition2</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;">(condition1)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 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><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>当 <code>MemberCondition</code> 已经设置 <code>MemberCondition.Configuration</code> 时将不再允许重复使用 <code>build(...)</code> 进行创建, 此时你需要使用 <code>copy()</code> 来复制并创建一份新的 <code>MemberCondition</code>。</p><p>同样地,<code>InstanceAwareResolver</code> 在通过 <code>MemberCondition.Configuration.memberInstance</code> 或 <code>of(instance)</code> 设置实例后也不允许重复设置新的实例, 此时你也需要使用 <code>copy()</code> 来复制并创建一份新的 <code>InstanceAwareResolver</code>。</p></div><h3 id="自定义解析器" tabindex="-1"><a class="header-anchor" href="#自定义解析器" aria-hidden="true">#</a> 自定义解析器</h3><p>KavaRef 使用默认的 <code>Member</code> 解析器进行过滤操作,如果你想实现自己的解析器,你可以自定义全局和每一个反射过程使用的解析器。</p><p>你可以继承于 <code>MemberProccessor.Resolver</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;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">MyMemberProcessorResolver</span><span style="color:#ADBAC7;"> : </span><span style="color:#F69D50;">MemberProcessor</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">Resolver</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</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;">> </span><span style="color:#DCBDFB;">getDeclaredConstructors</span><span style="color:#ADBAC7;">(declaringClass: </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">>): </span><span style="color:#F69D50;">List</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Constructor</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">>> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里拦截并实现你的构造方法过滤逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">return</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">getDeclaredConstructors</span><span style="color:#ADBAC7;">(declaringClass)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</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;">> </span><span style="color:#DCBDFB;">getDeclaredMethods</span><span style="color:#ADBAC7;">(declaringClass: </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">>): </span><span style="color:#F69D50;">List</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Method</span><span style="color:#ADBAC7;">> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里拦截并实现你的方法过滤逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">return</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">getDeclaredMethods</span><span style="color:#ADBAC7;">(declaringClass)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">override</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</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;">> </span><span style="color:#DCBDFB;">getDeclaredFields</span><span style="color:#ADBAC7;">(declaringClass: </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">>): </span><span style="color:#F69D50;">List</span><span style="color:#ADBAC7;"><</span><span style="color:#F69D50;">Field</span><span style="color:#ADBAC7;">> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 在这里拦截并实现你的字段过滤逻辑</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">return</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">super</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">getDeclaredFields</span><span style="color:#ADBAC7;">(declaringClass)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><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 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><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:#ADBAC7;">MemberProcessor.globalResolver </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MyMemberProcessorResolver</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>MemberCondition.Configuration</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;">// 创建解析器</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myResolver </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">MyMemberProcessorResolver</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 设置自定义解析器</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">processor</span><span style="color:#ADBAC7;">(myResolver)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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 class="line-number"></div><div class="line-number"></div></div></div>`,81),u={class:"custom-container tip"},m=n("p",{class:"custom-container-title"},"小提示",-1),b=a(`<h3 id="关于缓存" tabindex="-1"><a class="header-anchor" href="#关于缓存" aria-hidden="true">#</a> 关于缓存</h3><p>由于过滤条件的多样性,KavaRef 不直接提供缓存功能,根据每个开发者的实现方式不同,缓存的实现方式也会有所不同。</p><p>我们建议手动对过滤结果创建的 <code>MemberResolver</code> 实现缓存以提高性能并参考 <a href="#%E6%89%8B%E5%8A%A8%E5%88%9B%E5%BB%BA">手动创建</a> 拆分过滤条件以优化代码复用率。</p><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>如果你使用了 <code>val myResolver by lazy { ... }</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;"> myResolver </span><span style="color:#F47067;">by</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">lazy</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> Test::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">firstMethod</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"doTask"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><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></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:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">myResolver.</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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>MemberResolver</code> 已被缓存,在你每次引用它时调用的是同一个实例,而 <code>MemberResolver</code> 的实例对象不允许重复设置 (参考 <a href="#%E6%89%8B%E5%8A%A8%E5%88%9B%E5%BB%BA">手动创建</a> 下方的 “特别注意”), 所以直接这样调用会抛出异常,你需要改为以下形式。</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 的实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test: </span><span style="color:#F69D50;">Test</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">myResolver.</span><span style="color:#DCBDFB;">copy</span><span style="color:#ADBAC7;">().</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</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>MemberResolver</code> 实例而不需要重复反射过程,也不会抛出异常。</p></div><h3 id="java-用法" tabindex="-1"><a class="header-anchor" href="#java-用法" aria-hidden="true">#</a> Java 用法</h3><p>KavaRef 不推荐直接在 Java 中使用,因为它的 API 设计是基于 Kotlin 的特性和语法糖。</p><p>如果你需要在 Java 中使用 KavaRef,你可以使用以下方式来实现。</p><blockquote><p>示例如下</p></blockquote><div class="language-java line-numbers-mode" data-ext="java"><pre class="shiki github-dark-dimmed" style="background-color:#22272e;" tabindex="0"><code><span class="line"><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Main</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">main</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">String</span><span style="color:#ADBAC7;">[] </span><span style="color:#F69D50;">args</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 假设这就是这个 Class 的实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> Test</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">test;</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> KavaRef.</span><span style="color:#DCBDFB;">resolveClass</span><span style="color:#ADBAC7;">(Test.class)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"doTask"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String.class)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">build</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</span><span style="color:#ADBAC7;">);</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 或者,使用实例创建 KavaRef 反射</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> KavaRef.</span><span style="color:#DCBDFB;">resolveObject</span><span style="color:#ADBAC7;">(test)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">method</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">name</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"doTask"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">parameters</span><span style="color:#ADBAC7;">(String.class)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">build</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"task_name"</span><span style="color:#ADBAC7;">);</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><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 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 class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div>`,9);function F(h,k){const c=p("ExternalLinkIcon"),e=p("RouterLink");return t(),i("div",null,[A,n("p",null,[s("你可以 "),n("a",y,[s("点击这里"),l(c)]),s(" 查看 KDoc。")]),D,n("div",B,[v,n("p",null,[s("你也可以使用 "),l(e,{to:"/zh-cn/library/kavaref-extension.html"},{default:o(()=>[s("kavaref-extension")]),_:1}),s(" 中提供的 "),l(e,{to:"/zh-cn/library/kavaref-extension.html#%E5%88%9B%E5%BB%BA-class-%E5%AF%B9%E8%B1%A1"},{default:o(()=>[s("创建 Class 对象")]),_:1}),s(" 来解决这个问题。")])]),C,n("div",u,[m,n("p",null,[s("你可以在 "),l(e,{to:"/zh-cn/config/processor-resolvers.html"},{default:o(()=>[s("这里")]),_:1}),s(" 找到一些公开维护的自定义解析器,定义在你的项目中即可使用。")])]),b])}const f=r(d,[["render",F],["__file","kavaref-core.html.vue"]]);export{f as default};
|