Files
KavaRef/assets/migration.html-Ye0WsuNZ.js
github-actions[bot] 29b7fb4ab9 Deploy to GitHub pages
2025-08-02 18:18:10 +00:00

66 lines
29 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{_ as c,r as t,o as i,c as p,b as s,d as e,e as n,w as a,a as d}from"./app-mh6GuRj9.js";const r={},u=s("h1",{id:"migration-to-kavaref",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#migration-to-kavaref","aria-hidden":"true"},"#"),e(" Migration to KavaRef")],-1),y={href:"https://github.com/HighCapable/YukiReflection",target:"_blank",rel:"noopener noreferrer"},v={href:"https://github.com/HighCapable/YukiHookAPI",target:"_blank",rel:"noopener noreferrer"},A=s("code",null,"KavaRef",-1),m=d(`<div class="custom-container warning"><p class="custom-container-title">Notice</p><p>For <code>YukiHookAPI</code>, you need to continue using its Hook API, and <code>KavaRef</code> only includes Java reflection-related APIs.</p></div><h2 id="basic-functions" tabindex="-1"><a class="header-anchor" href="#basic-functions" aria-hidden="true">#</a> Basic Functions</h2><p>The design concept of <code>KavaRef</code> is similar to <code>YukiReflection</code>, but not exactly the same. The following lists the differences between <code>YukiReflection</code> and <code>KavaRef</code> in basic reflection functions, which you can manually migrate based on.</p><p>For example, we have the following Java class.</p><blockquote><p>The following example</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;">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;">&quot;Hello &quot;</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;">&quot;!&quot;</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>Here is a comparison of <code>KavaRef</code> with <code>YukiReflection</code> using examples.</p><blockquote><p>The following example</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;">// Assume that&#39;s your MyClass instance.</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;">// Call and execute using 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;">&quot;myMethod&quot;</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;">&quot;Hello, KavaRef!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// Direct reference to instance.</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;">&quot;myMethod&quot;</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;">&quot;Hello, KavaRef!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div 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;">// Assume that&#39;s your MyClass instance.</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;">// Call and execute using 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;">&quot;myMethod&quot;</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;">&quot;Hello, YukiReflection!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"><span style="color:#768390;">// Direct reference to instance.</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;">&quot;myMethod&quot;</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;">&quot;Hello, YukiReflection!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div 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> starts reflection at any time; you need to use <code>resolve()</code> to create a reflection scope. You no longer directly extend the related <code>method</code> and <code>constructor</code> methods to avoid polluting their scope.</p><p><code>KavaRef</code> provides the <code>asResolver()</code> method to directly reference the reflection scope of the instance object, avoiding pollution caused by the creation of uncontrollable instance objects by the <code>current()</code> method in <code>YukiReflection</code>.</p><p><code>KavaRef</code> abandons the &quot;Finder&quot; design concept and uses the &quot;Filter&quot; design concept to obtain reflection results. &quot;Find&quot; is no longer finding, but &quot;filtering&quot;.</p><p><code>KavaRef</code> canceled the design scheme defined in <code>YukiReflection</code> for determining whether the <code>Member</code> obtained in the resulting instance is multiple or single, and directly returns the entire <code>List&lt;MemberResolver&gt;</code>. The example you see above uses <code>firstMethod</code> to get the first matching <code>MethodResolver</code>. If you need to get all matches, you can change to <code>method</code>.</p><p>The conditional method name in <code>MethodCondition</code> of <code>KavaRef</code> has been modified from abbreviations such as <code>param</code> used previously in <code>YukiReflection</code> to <code>parameters</code> to better align with the naming conventions of the Java reflection API.</p><p><code>KavaRef</code> no longer provides the <code>param(...).order()</code> function in conditions, because this function itself is unstable. <code>KavaRef</code> now uses an iterator for filtering, and the bytecode will no longer be in order, nor should bytecode be filtered by order. You can use <code>firstMethod</code>, <code>firstField</code>, or <code>lastMethod</code>, <code>lastField</code>, etc. to get the first or last matching result.</p><p><code>KavaRef</code> renames the <code>get(instance)</code> method to <code>of(instance)</code> because <code>get(...)</code> may be confused with the <code>get(...)</code> usage of <code>Field</code> and lacks semantic clarity. At the same time, <code>get(instance)</code> no longer gets the <code>MethodFinder.Result.Instance</code> instance from something like <code>MethodFinder.Result</code>, but uses <code>of(instance)</code> to consistently operate and set the instance object to <code>MemberResolver</code>.</p><p>Methods such as <code>string()</code>, <code>int()</code>, etc. in <code>MethodFinder.Result.Instance</code> have been removed in <code>KavaRef</code>. You can directly use <code>get&lt;String&gt;()</code>, <code>get&lt;Int&gt;()</code>, <code>invoke&lt;String&gt;(...)</code>, <code>invoke&lt;Int&gt;(...)</code>, etc. to get or call the corresponding type results.</p><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>If you are looking for (filtering) <code>Field</code>, you need to note that there may be semantic conflicts between <code>KavaRef</code> and <code>YukiReflection</code> in the acquisition method of <code>Field</code>. Please pay special attention when migrating this part.</p><p>For example, get the static field of <code>content</code> in <code>MyClass</code>, in <code>YukiReflection</code>, you would do this.</p><blockquote><p>The following example</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;">&quot;content&quot;</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// Return 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;">// Cannot be omitted, return 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;">// value</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>In <code>KavaRef</code> you need to do this.</p><blockquote><p>The following example</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;">&quot;content&quot;</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// Return FieldResolver&lt;MyClass&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;">&gt;() </span><span style="color:#768390;">// value</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>As mentioned above, <code>get(...)</code> is used to get the <code>FieldFinder.Result.Instance</code> object in Y<code>ukiReflection</code>, not the value. To get the value and process it as a specified type, you need to call <code>string()</code> or <code>cast&lt;String&gt;()</code>, and in <code>KavaRef</code>, you use <code>get&lt;T&gt;()</code> directly in <code>MemberResolver</code> to get the value of the specified type. The usage of <code>get(...)</code> of <code>KavaRef</code> for <code>get(...)</code> to <code>of(...)</code>.</p><p>So the complete writing of the above example in <code>KavaRef</code> should be.</p><blockquote><p>The following example</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;">// Since the call is a static instance, &quot;of(null)&quot; can be omitted.</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;">&quot;content&quot;</span><span style="color:#ADBAC7;"> } </span><span style="color:#768390;">// It&#39;s already a call chain object FieldResolver&lt;MyClass&gt;</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;">// Can be omitted and return to the call chain object FieldResolver&lt;MyClass&gt;</span></span>
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#DCBDFB;">get</span><span style="color:#ADBAC7;">&lt;</span><span style="color:#F69D50;">String</span><span style="color:#ADBAC7;">&gt;() </span><span style="color:#768390;">// value</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> no longer provides <code>call</code> methods for <code>Method</code>, and is now merged uniformly into <code>invoke</code> (with generic parameters). At the same time, <code>KavaRef</code> defines the <code>newInstance</code> method of <code>Constructor</code> as <code>create</code> (with generic parameters).</p><p>You may have noticed that the condition <code>superClass()</code> is gone, it is still there, in <code>KavaRef</code> it has been renamed to <code>superclass()</code>, docking with the standard Java reflection API.</p><p>At the same time, <code>KavaRef</code> extends <code>KClass</code>, and you no longer need to use <code>Some::class.java</code> to declare an instance of <code>Class</code> in most scenarios.</p><p>Another design idea of <code>KavaRef</code> is type safety. As long as you use <code>KClass&lt;T&gt;</code> and <code>Class&lt;T&gt;</code> that declare the generic type, it will be checked and converted to the corresponding type when <code>of(instance)</code> and <code>create(...)</code>, and type checking will be completed during coding to avoid runtime errors.</p><blockquote><p>The following example</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;">// Assume that&#39;s your MyClass instance.</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;">// Using KavaRef to call and execute.</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;">&quot;myMethod&quot;</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;">// Only instances of type MyClass can be passed in.</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;">&quot;Hello, KavaRef!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div 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="other-functions" tabindex="-1"><a class="header-anchor" href="#other-functions" aria-hidden="true">#</a> Other Functions</h2><p><code>KavaRef</code> and <code>YukiReflection</code> are not much different in other functions and extended functions. <code>KavaRef</code> separates these functions into a separate module.</p><p>The following functionality is provided in <code>YukiReflection</code> but is not implemented and no longer provided in <code>KavaRef</code>:</p><ul><li><p>Preset reflection type constant classes, such as <code>StringClass</code>, <code>IntType</code>, etc</p><ul><li>You can use Kotlin class references such as <code>String::class</code>, <code>Int::class</code>, etc. to instead it. For primitive types and wrapper classes, <code>IntType</code> is equivalent to <code>Int::class</code>, and <code>IntClass</code> is equivalent to <code>JInteger::class</code></li></ul></li><li><p><code>DexClassFinder</code> function</p><ul><li>Due to its design flaws and possible performance issues when used on Android platforms, it is no longer available for now</li></ul></li><li><p><code>RemedyPlan</code> and <code>method { ... } .remedys { ... }</code> functions</p><ul><li>Due to possible black box problems, maintenance is relatively difficult. If you need to use similar functions, please implement them manually and will no longer be provided</li></ul></li><li><p><code>ClassLoader.listOfClasses()</code> function</p><ul><li>Due to the complex and unstable implementation solutions of each platform, it will no longer be provided</li></ul></li><li><p><code>ClassLoader.searchClass()</code> function</p><ul><li>Due to performance issues and design time is limited to Android platform, it is relatively difficult to maintain filter conditions and is no longer provided</li></ul></li><li><p><code>Class.hasExtends</code>, <code>Class.extends</code>, <code>Class.implements</code> functions</p><ul><li>You can replace them with <code>A::class isSubclassOf B::class</code></li></ul></li><li><p><code>Class.toJavaPrimitiveType()</code> function</p><ul><li>There is conceptual confusion in functional design and will no longer be provided</li></ul></li><li><p><code>&quot;com.some.clazz&quot;.hasClass(loader)</code> function</p><ul><li>You can use <code>loader.hasClass(&quot;com.some.clazz&quot;)</code> to instead it</li></ul></li><li><p><code>Class.hasField</code>, <code>Class.hasMethod</code>, <code>Class.hasConstructor</code> functions</p><ul><li>Due to design defects, no longer provided</li></ul></li><li><p><code>Class.hasModifiers(...)</code>, <code>Member.hasModifiers(...)</code> functions</p><ul><li>You can replace them directly with extension methods such as <code>Class.isPublic</code>, <code>Member.isPublic</code></li></ul></li><li><p><code>Class.generic()</code>, <code>GenericClass</code> functions</p><ul><li>If you just want to get generic parameters of the superclass, you can use <code>Class.genericSuperclassTypeArguments()</code>. Due to design defects, no longer provided</li></ul></li><li><p><code>Any.current()</code>, <code>CurrentClass</code> functions</p><ul><li>You can use <code>Any.asResolver()</code> to instead it</li></ul></li><li><p><code>Class.buildOf(...)</code> function</p><ul><li>You can use <code>Class.createInstance(...)</code> to instead it</li></ul></li><li><p><code>Class.allMethods()</code>, <code>Class.allFields()</code>, <code>Class.allConstructors()</code> functions</p><ul><li>Due to its pollution scope, no longer provided</li></ul></li><li><p><code>YLog</code> log function</p><ul><li><code>KavaRef</code> no longer takes over the logs, you can use the corresponding platform implementation method and no longer provided</li></ul></li></ul><h2 id="exception-handling" tabindex="-1"><a class="header-anchor" href="#exception-handling" aria-hidden="true">#</a> Exception Handling</h2><p><code>KavaRef</code> is completely different from <code>YukiReflection</code> in exception handling. The exception logic of <code>KavaRef</code> will remain transparent by default. <u><strong>It no longer actively intercepts exceptions and prints error logs or even provides <code>onNoSuchMethod</code> listener</strong></u>. When no valid members are filtered, <code>KavaRef</code> will throw an exception directly unless you <strong>explicitly declare the condition as optional (consistent with <code>YukiReflection</code> logic)</strong>.</p><blockquote><p>The following example</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;">// Assume that&#39;s your MyClass instance.</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;">// Using KavaRef to call and execute.</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;">// Declare as optional, do not throw exceptions.</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Use firstMethodOrNull instead of firstMethod,</span></span>
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// because the NoSuchElementException of Kotlin itself will be thrown.</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;">&quot;doNonExistentMethod&quot;</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume that this method does not exist.</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;">&quot;Hello, KavaRef!&quot;</span><span style="color:#ADBAC7;">)</span></span>
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div 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),h=s("h2",{id:"new-to-kavaref",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#new-to-kavaref","aria-hidden":"true"},"#"),e(" New to KavaRef")],-1),D=s("p",null,[e("If you haven't used "),s("code",null,"YukiReflection"),e(" or "),s("code",null,"YukiHookAPI"),e(", it doesn't matter, you can refer to the following content to get started quickly.")],-1),C={class:"custom-container tip"},f=s("p",{class:"custom-container-title"},"What to Do Next",-1),B=s("p",null,[e("Get started using "),s("code",null,"KavaRef"),e(" now!")],-1);function g(b,F){const l=t("ExternalLinkIcon"),o=t("RouterLink");return i(),p("div",null,[u,s("p",null,[e("If you are used to using the reflection API in "),s("a",y,[e("YukiReflection"),n(l)]),e(" or "),s("a",v,[e("YukiHookAPI"),n(l)]),e(", you can refer to the following to migrate to "),A,e(".")]),m,s("p",null,[e("For more information, please refer to the "),n(o,{to:"/en/library/kavaref-core.html#exception-handling"},{default:a(()=>[e("Exception Handling")]),_:1}),e(" section in "),n(o,{to:"/en/library/kavaref-core.html"},{default:a(()=>[e("kavaref-core")]),_:1}),e(".")]),h,D,s("div",C,[f,s("p",null,[e("For more information, please continue reading "),n(o,{to:"/en/library/kavaref-core.html"},{default:a(()=>[e("kavaref-core")]),_:1}),e(" and "),n(o,{to:"/en/library/kavaref-extension.html"},{default:a(()=>[e("kavaref-extension")]),_:1}),e(".")]),B])])}const R=c(r,[["render",g],["__file","migration.html.vue"]]);export{R as default};