mirror of
https://github.com/HighCapable/KavaRef.git
synced 2025-09-06 02:35:21 +08:00
67 lines
29 KiB
JavaScript
67 lines
29 KiB
JavaScript
import{_ as p,r as c,o as t,c as d,b as e,d as s,e as a,w as n,a as i}from"./app-mh6GuRj9.js";const r={},y=e("h1",{id:"迁移至-kavaref",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#迁移至-kavaref","aria-hidden":"true"},"#"),s(" 迁移至 KavaRef")],-1),A={href:"https://github.com/HighCapable/YukiReflection",target:"_blank",rel:"noopener noreferrer"},u={href:"https://github.com/HighCapable/YukiHookAPI",target:"_blank",rel:"noopener noreferrer"},D=e("code",null,"KavaRef",-1),C=i(`<div class="custom-container warning"><p class="custom-container-title">注意</p><p>针对 <code>YukiHookAPI</code>,你需要继续使用其 Hook API,<code>KavaRef</code> 仅包含 Java 反射相关 API。</p></div><h2 id="基本功能" tabindex="-1"><a class="header-anchor" href="#基本功能" aria-hidden="true">#</a> 基本功能</h2><p><code>KavaRef</code> 的设计理念与 <code>YukiReflection</code> 类似,但不完全相同,以下内容列举了 <code>YukiReflection</code> 与 <code>KavaRef</code> 在基本反射功能上的差异,你可以根据这些差异手动进行迁移。</p><p>例如我们有以下 Java 类。</p><blockquote><p>示例如下</p></blockquote><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;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">MyClass</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;">static</span><span style="color:#ADBAC7;"> String</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">content</span><span style="color:#F69D50;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"Hello, World!"</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;">myMethod</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">content</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> System.out.</span><span style="color:#DCBDFB;">println</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello "</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">+</span><span style="color:#ADBAC7;"> content </span><span style="color:#F47067;">+</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"!"</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><p>以下是 <code>KavaRef</code> 与 <code>YukiReflection</code> 的使用示例对比。</p><blockquote><p>示例如下</p></blockquote><div style="display:flex;gap:16px;"><div style="flex:1;"><h4>KavaRef</h4><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;">// 假设这就是你的 MyClass 实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass: </span><span style="color:#F69D50;">MyClass</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.</span><span style="color:#DCBDFB;">resolve</span><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;">"myMethod"</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;">(myClass).</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello, KavaRef!"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 直接引用实例方式</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">myClass.</span><span style="color:#DCBDFB;">asResolver</span><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;">"myMethod"</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;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello, KavaRef!"</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></div><div style="flex:1;"><h4>YukiReflection</h4><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;">// 假设这就是你的 MyClass 实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass: </span><span style="color:#F69D50;">MyClass</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 YukiReflection 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java.</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;">"myMethod"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">(myClass).</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello, YukiReflection!"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// 直接引用实例方式</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">myClass.</span><span style="color:#DCBDFB;">current</span><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;">"myMethod"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">param</span><span style="color:#ADBAC7;">(StringClass)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.</span><span style="color:#DCBDFB;">call</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello, YukiReflection!"</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></div></div><p><code>KavaRef</code> 在任何时候开始反射都需要使用 <code>resolve()</code> 来创建反射作用域,不再对 <code>Class</code> 等实例直接进行扩展相关 <code>method</code>、<code>constructor</code> 方法以避免污染其作用域。</p><p><code>KavaRef</code> 提供了 <code>asResolver()</code> 方法来直接引用实例对象的反射作用域,避免了 <code>YukiReflection</code> 中的 <code>current()</code> 方法创建不可控实例对象造成的污染。</p><p><code>KavaRef</code> 抛弃了 "Finder" 的设计理念,使用 "Filter" (过滤器) 的设计理念来获取反射结果,“查找” 不再是查找,而是 “过滤”。</p><p><code>KavaRef</code> 取消了 <code>YukiReflection</code> 在结果实例中定义获取的 <code>Member</code> 为多重还是单一的设计方案,直接返回整个 <code>List<MemberResolver></code>, 你在上方看到的示例使用了 <code>firstMethod</code> 来获取第一个匹配的 <code>MethodResolver</code>,如果你需要获取所有匹配的结果,可以改为 <code>method</code>。</p><p><code>KavaRef</code> 在 <code>MethodCondition</code> 中的条件方法名称已由 <code>YukiReflection</code> 之前的 <code>param</code> 等简写修改为 <code>parameters</code>,以更符合 Java 反射 API 的命名习惯。</p><p><code>KavaRef</code> 不再提供条件中的 <code>param(...).order()</code> 功能,因为这个功能本身就不稳定,<code>KavaRef</code> 现在使用迭代器进行过滤操作,字节码将不再有顺序,且本不应该使用顺序筛选字节码,你可以使用 <code>firstMethod</code>、<code>firstField</code> 或 <code>lastMethod</code>、<code>lastField</code> 等方法来获取第一个或最后一个匹配的结果。</p><p><code>KavaRef</code> 将 <code>get(instance)</code> 方法更名为 <code>of(instance)</code>,因为 <code>get(...)</code> 可能会与 <code>Field</code> 的 <code>get(...)</code> 用法产生混淆且语义不明确, 同时 <code>get(instance)</code> 也不再是从类似 <code>MethodFinder.Result</code> 来获取 <code>MethodFinder.Result.Instance</code> 实例,而是使用 <code>of(instance)</code> 来始终操作和设置实例对象到 <code>MemberResolver</code>。</p><p>类似 <code>MethodFinder.Result.Instance</code> 中的 <code>string()</code>、<code>int()</code> 等方法在 <code>KavaRef</code> 中已被移除, 你可以直接使用 <code>get<String>()</code>、<code>get<Int>()</code>、<code>invoke<String>(...)</code>、<code>invoke<Int>(...)</code> 等方式来获取或调用对应类型的结果。</p><div class="custom-container danger"><p class="custom-container-title">特别注意</p><p>如果你正在查找 (过滤) <code>Field</code>,你需要注意 <code>KavaRef</code> 与 <code>YukiReflection</code> 在 <code>Field</code> 的获取方式上有可能会发生语义冲突,在迁移这部分的时候请特别注意。</p><p>例如获取 <code>MyClass</code> 中的 <code>content</code> 静态字段,在 <code>YukiReflection</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;">MyClass::</span><span style="color:#DCBDFB;">class</span><span style="color:#ADBAC7;">.java</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">field</span><span style="color:#ADBAC7;"> { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"content"</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 返回 FieldFinder.Result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 不可省略,返回 FieldFinder.Result.Instance</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">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></div><p>在 <code>KavaRef</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;">MyClass::</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;"> { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"content"</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 返回 FieldResolver<MyClass></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></div><p>正如上面所说,<code>get(...)</code> 在 <code>YukiReflection</code> 中是获取 <code>FieldFinder.Result.Instance</code> 对象,而不是值,要获取值并处理为指定类型,你需要调用 <code>string()</code> 或者 <code>cast<String>()</code>,而在 <code>KavaRef</code> 中是在 <code>MemberResolver</code> 中直接使用 <code>get<T>()</code> 来获取指定类型的值,<code>KavaRef</code> 对应 <code>YukiReflection</code> 的 <code>get(...)</code> 的用法是 <code>of(...)</code>。</p><p>所以上述示例在 <code>KavaRef</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;">// 由于调用的是静态实例,"of(null)" 可被省略</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">MyClass::</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;"> { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"content"</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// 已是调用链对象 FieldResolver<MyClass></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">null</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// 可省略,返回调用链对象 FieldResolver<MyClass></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></div></div><p><code>KavaRef</code> 不再对 <code>Method</code> 提供 <code>call</code> 方法,现在统一合并为 <code>invoke</code> (带泛型参数),同时 <code>KavaRef</code> 将 <code>Constructor</code> 的 <code>newInstance</code> 方法定义为 <code>create</code> (带泛型参数)。</p><p>你可能注意到条件 <code>superClass()</code> 消失了,它还在,在 <code>KavaRef</code> 中它已更名为 <code>superclass()</code>,对接标准的 Java 反射 API。</p><p>同时,<code>KavaRef</code> 对 <code>KClass</code> 进行了扩展,你不再需要在大部分场景中使用 <code>Some::class.java</code> 的方式来声明一个 <code>Class</code> 实例。</p><p><code>KavaRef</code> 的另一个设计思想就是类型安全,只要是你在使用声明指定泛型类型的 <code>KClass<T></code>、<code>Class<T></code> 时,在 <code>of(instance)</code>、<code>create(...)</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;">// 假设这就是你的 MyClass 实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass: </span><span style="color:#F69D50;">MyClass</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">MyClass::</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;">"myMethod"</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;">// 只能传入 MyClass 类型的实例</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">of</span><span style="color:#ADBAC7;">(myClass)</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;">"Hello, KavaRef!"</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><h2 id="其它功能" tabindex="-1"><a class="header-anchor" href="#其它功能" aria-hidden="true">#</a> 其它功能</h2><p><code>KavaRef</code> 与 <code>YukiReflection</code> 在其它功能及扩展功能中的实现差异不大,<code>KavaRef</code> 将这些功能单独分离为了一个独立的模块。</p><p>以下功能在 <code>YukiReflection</code> 中提供,但在 <code>KavaRef</code> 中没有实现且不再提供:</p><ul><li><p>预置反射类型常量类,如 <code>StringClass</code>、<code>IntType</code> 等</p><ul><li>你可以直接使用 <code>String::class</code>、<code>Int::class</code> 等 Kotlin 的类引用进行替代,对于原始类型与包装类,<code>IntType</code> 等价于 <code>Int::class</code>,<code>IntClass</code> 等价于 <code>JInteger::class</code></li></ul></li><li><p><code>DexClassFinder</code> 功能</p><ul><li>由于其设计缺陷,且在 Android 平台上使用时可能存在性能问题,目前不再提供</li></ul></li><li><p><code>RemedyPlan</code> 和 <code>method { ... } .remedys { ... }</code> 功能</p><ul><li>由于此功能存在可能的黑盒问题,维护相对困难,如需使用类似功能,请手动实现,不再提供</li></ul></li><li><p><code>ClassLoader.listOfClasses()</code> 功能</p><ul><li>由于各个平台实现方案复杂且不稳定,不再提供</li></ul></li><li><p><code>ClassLoader.searchClass()</code> 功能</p><ul><li>由于性能问题,且设计时仅限于 Android 平台使用,过滤条件维护相对困难,不再提供</li></ul></li><li><p><code>Class.hasExtends</code>、<code>Class.extends</code>、<code>Class.implements</code> 功能</p><ul><li>你可以使用 <code>A::class isSubclassOf B::class</code> 来取代它们</li></ul></li><li><p><code>Class.toJavaPrimitiveType()</code> 功能</p><ul><li>功能设计上存在概念混淆问题,不再提供</li></ul></li><li><p><code>"com.some.clazz".hasClass(loader)</code> 功能</p><ul><li>你可以使用 <code>loader.hasClass("com.some.clazz")</code> 来取代它</li></ul></li><li><p><code>Class.hasField</code>、<code>Class.hasMethod</code>、<code>Class.hasConstructor</code> 功能</p><ul><li>由于设计缺陷,不再提供</li></ul></li><li><p><code>Class.hasModifiers(...)</code>、<code>Member.hasModifiers(...)</code> 功能</p><ul><li>你可以直接使用 <code>Class.isPublic</code>、<code>Member.isPublic</code> 等扩展方法来取代它们。</li></ul></li><li><p><code>Class.generic()</code>、<code>GenericClass</code> 功能</p><ul><li>如果只是希望获取超类的泛型参数,你可以使用 <code>Class.genericSuperclassTypeArguments()</code>,由于设计缺陷,不再提供</li></ul></li><li><p><code>Any.current()</code>、<code>CurrentClass</code> 功能</p><ul><li>你可以使用 <code>Any.asResolver()</code> 来取代它</li></ul></li><li><p><code>Class.buildOf(...)</code> 功能</p><ul><li>你可以使用 <code>Class.createInstance(...)</code> 来取代它</li></ul></li><li><p><code>Class.allMethods()</code>、<code>Class.allFields()</code>、<code>Class.allConstructors()</code> 功能</p><ul><li>由于其污染作用域,不再提供</li></ul></li><li><p><code>YLog</code> 日志功能</p><ul><li><code>KavaRef</code> 不再接管日志,你可以使用对应平台的实现方式,不再提供</li></ul></li></ul><h2 id="异常处理" tabindex="-1"><a class="header-anchor" href="#异常处理" aria-hidden="true">#</a> 异常处理</h2><p><code>KavaRef</code> 在异常处理方面与 <code>YukiReflection</code> 完全不同,<code>KavaRef</code> 的异常逻辑将保持默认透明,<u><strong>它不再主动拦截异常并打印错误日志甚至是提供 <code>onNoSuchMethod</code> 监听</strong></u>,当没有过滤到任何有效的成员时,<code>KavaRef</code> 会直接抛出异常,除非你<strong>明确声明条件为可选 (与 <code>YukiReflection</code> 逻辑保持一致)</strong>。</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;">// 假设这就是你的 MyClass 实例</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> myClass: </span><span style="color:#F69D50;">MyClass</span></span>
|
||
<span class="line"><span style="color:#768390;">// 使用 KavaRef 调用并执行</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">MyClass::</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;">optional</span><span style="color:#ADBAC7;">() </span><span style="color:#768390;">// 声明为可选,不要抛出异常</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// 使用 firstMethodOrNull 替代 firstMethod,因为找不到会抛出 Kotlin 自身的 NoSuchElementException</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 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;">(myClass)?.</span><span style="color:#DCBDFB;">invoke</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"Hello, KavaRef!"</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>`,32),v=e("h2",{id:"初次使用-kavaref",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#初次使用-kavaref","aria-hidden":"true"},"#"),s(" 初次使用 KavaRef")],-1),B=e("p",null,[s("如果你没用过 "),e("code",null,"YukiReflection"),s(" 或者 "),e("code",null,"YukiHookAPI"),s(",没关系,你可以参考以下内容来快速上手。")],-1),m={class:"custom-container tip"},F=e("p",{class:"custom-container-title"},"接下来做什么",-1),b=e("p",null,[s("立即开始使用 "),e("code",null,"KavaRef"),s(" 吧!")],-1);function h(f,k){const o=c("ExternalLinkIcon"),l=c("RouterLink");return t(),d("div",null,[y,e("p",null,[s("如果你已经习惯使用 "),e("a",A,[s("YukiReflection"),a(o)]),s(" 或 "),e("a",u,[s("YukiHookAPI"),a(o)]),s(" 中的反射 API,你可以参考以下内容来迁移至 "),D,s("。")]),C,e("p",null,[s("更多内容请参考 "),a(l,{to:"/zh-cn/library/kavaref-core.html"},{default:n(()=>[s("kavaref-core")]),_:1}),s(" 中的 "),a(l,{to:"/zh-cn/library/kavaref-core.html#%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86"},{default:n(()=>[s("异常处理")]),_:1}),s(" 部分。")]),v,B,e("div",m,[F,e("p",null,[s("更多内容,请继续阅读 "),a(l,{to:"/zh-cn/library/kavaref-core.html"},{default:n(()=>[s("kavaref-core")]),_:1}),s(" 和 "),a(l,{to:"/zh-cn/library/kavaref-extension.html"},{default:n(()=>[s("kavaref-extension")]),_:1}),s("。")]),b])])}const R=p(r,[["render",h],["__file","migration.html.vue"]]);export{R as default};
|