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 Permalink 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};