mirror of
https://github.com/HighCapable/YukiReflection.git
synced 2025-09-06 10:45:46 +08:00
804 lines
238 KiB
HTML
804 lines
238 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en-US">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<meta name="generator" content="VuePress 2.0.0-beta.51">
|
||
<style>
|
||
:root {
|
||
--c-bg: #fff;
|
||
}
|
||
html.dark {
|
||
--c-bg: #22272e;
|
||
}
|
||
html, body {
|
||
background-color: var(--c-bg);
|
||
}
|
||
</style>
|
||
<script>
|
||
const userMode = localStorage.getItem('vuepress-color-scheme');
|
||
const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||
if (userMode === 'dark' || (userMode !== 'light' && systemDarkMode)) {
|
||
document.documentElement.classList.toggle('dark', true);
|
||
}
|
||
</script>
|
||
<link rel="icon" href="/YukiReflection/images/logo.png"><title>Features | Yuki Reflection</title><meta name="description" content="An efficient Reflection API for the Android platform built in Kotlin">
|
||
<link rel="modulepreload" href="/YukiReflection/assets/app.3cb5b3a5.js"><link rel="modulepreload" href="/YukiReflection/assets/features.html.8d011c3c.js"><link rel="modulepreload" href="/YukiReflection/assets/features.html.360a180c.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.7c46b7b0.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.52fbcda7.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.1356aa63.js"><link rel="prefetch" href="/YukiReflection/assets/about.html.2effd4b1.js"><link rel="prefetch" href="/YukiReflection/assets/changelog.html.01288623.js"><link rel="prefetch" href="/YukiReflection/assets/contacts.html.96dbd22d.js"><link rel="prefetch" href="/YukiReflection/assets/future.html.aa0c285e.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.817a2e55.js"><link rel="prefetch" href="/YukiReflection/assets/api-example.html.6daf2d5c.js"><link rel="prefetch" href="/YukiReflection/assets/api-exception.html.58702900.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.89a39f8e.js"><link rel="prefetch" href="/YukiReflection/assets/quick-start.html.fb6e2746.js"><link rel="prefetch" href="/YukiReflection/assets/about.html.b758f732.js"><link rel="prefetch" href="/YukiReflection/assets/changelog.html.eb0b25c0.js"><link rel="prefetch" href="/YukiReflection/assets/contacts.html.f15acc18.js"><link rel="prefetch" href="/YukiReflection/assets/future.html.a5999f89.js"><link rel="prefetch" href="/YukiReflection/assets/features.html.57dae594.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.a2b832f6.js"><link rel="prefetch" href="/YukiReflection/assets/api-example.html.90859470.js"><link rel="prefetch" href="/YukiReflection/assets/api-exception.html.6f5a5377.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.77f6fdb1.js"><link rel="prefetch" href="/YukiReflection/assets/quick-start.html.49d48274.js"><link rel="prefetch" href="/YukiReflection/assets/YukiReflection.html.071d5ea0.js"><link rel="prefetch" href="/YukiReflection/assets/YukiReflection.html.787cb57f.js"><link rel="prefetch" href="/YukiReflection/assets/CurrentClass.html.4fb3c7c5.js"><link rel="prefetch" href="/YukiReflection/assets/GenericClass.html.18ef844b.js"><link rel="prefetch" href="/YukiReflection/assets/VariousClass.html.be531e78.js"><link rel="prefetch" href="/YukiReflection/assets/ReflectionFactory.html.660311db.js"><link rel="prefetch" href="/YukiReflection/assets/ReflectionFactory.html.79e3b099.js"><link rel="prefetch" href="/YukiReflection/assets/DefinedTypeFactory.html.b02e4f3c.js"><link rel="prefetch" href="/YukiReflection/assets/ComponentTypeFactory.html.90290523.js"><link rel="prefetch" href="/YukiReflection/assets/GraphicsTypeFactory.html.c8903b11.js"><link rel="prefetch" href="/YukiReflection/assets/ViewTypeFactory.html.b4b99faf.js"><link rel="prefetch" href="/YukiReflection/assets/VariableTypeFactory.html.271d7de9.js"><link rel="prefetch" href="/YukiReflection/assets/CurrentClass.html.1f324cf5.js"><link rel="prefetch" href="/YukiReflection/assets/GenericClass.html.80c441b8.js"><link rel="prefetch" href="/YukiReflection/assets/VariousClass.html.7a95c6f9.js"><link rel="prefetch" href="/YukiReflection/assets/DexClassFinder.html.7f9c18ee.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorFinder.html.91c23734.js"><link rel="prefetch" href="/YukiReflection/assets/FieldFinder.html.d5dcfef4.js"><link rel="prefetch" href="/YukiReflection/assets/MethodFinder.html.704be21f.js"><link rel="prefetch" href="/YukiReflection/assets/BaseFinder.html.fb47fda7.js"><link rel="prefetch" href="/YukiReflection/assets/VariableTypeFactory.html.a7e09e1f.js"><link rel="prefetch" href="/YukiReflection/assets/DefinedTypeFactory.html.5311d687.js"><link rel="prefetch" href="/YukiReflection/assets/ComponentTypeFactory.html.23cb1ea0.js"><link rel="prefetch" href="/YukiReflection/assets/GraphicsTypeFactory.html.ede0ac1a.js"><link rel="prefetch" href="/YukiReflection/assets/ViewTypeFactory.html.8faf3b20.js"><link rel="prefetch" href="/YukiReflection/assets/BaseFinder.html.69bb751c.js"><link rel="prefetch" href="/YukiReflection/assets/DexClassFinder.html.e0965adb.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorFinder.html.372473c1.js"><link rel="prefetch" href="/YukiReflection/assets/FieldFinder.html.71816419.js"><link rel="prefetch" href="/YukiReflection/assets/MethodFinder.html.3e0643fa.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorRules.html.7769fbd0.js"><link rel="prefetch" href="/YukiReflection/assets/FieldRules.html.cc84b291.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRules.html.2d5c89a4.js"><link rel="prefetch" href="/YukiReflection/assets/MethodRules.html.46e12f82.js"><link rel="prefetch" href="/YukiReflection/assets/CountRules.html.aa55eac0.js"><link rel="prefetch" href="/YukiReflection/assets/ModifierRules.html.bf55a30e.js"><link rel="prefetch" href="/YukiReflection/assets/NameRules.html.2124d233.js"><link rel="prefetch" href="/YukiReflection/assets/ObjectRules.html.0a6223eb.js"><link rel="prefetch" href="/YukiReflection/assets/CountRules.html.69b807a7.js"><link rel="prefetch" href="/YukiReflection/assets/ModifierRules.html.063cc2f9.js"><link rel="prefetch" href="/YukiReflection/assets/NameRules.html.538d5551.js"><link rel="prefetch" href="/YukiReflection/assets/ObjectRules.html.ec943416.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorRules.html.ed54d54f.js"><link rel="prefetch" href="/YukiReflection/assets/FieldRules.html.0a9d082d.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRules.html.94fb57e3.js"><link rel="prefetch" href="/YukiReflection/assets/MethodRules.html.c94c00ea.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRulesResult.html.0df424dd.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRulesResult.html.aa74ca3c.js"><link rel="prefetch" href="/YukiReflection/assets/404.html.c038a05a.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.cdd3cd27.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.a0c6cad9.js"><link rel="prefetch" href="/YukiReflection/assets/index.html.f2ed3843.js"><link rel="prefetch" href="/YukiReflection/assets/about.html.8e88f1c3.js"><link rel="prefetch" href="/YukiReflection/assets/changelog.html.ab4084af.js"><link rel="prefetch" href="/YukiReflection/assets/contacts.html.1225422c.js"><link rel="prefetch" href="/YukiReflection/assets/future.html.82378e9b.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.04faba46.js"><link rel="prefetch" href="/YukiReflection/assets/api-example.html.59051e7e.js"><link rel="prefetch" href="/YukiReflection/assets/api-exception.html.bcc6510b.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.81e1e5ee.js"><link rel="prefetch" href="/YukiReflection/assets/quick-start.html.c524d8d1.js"><link rel="prefetch" href="/YukiReflection/assets/about.html.98e35d05.js"><link rel="prefetch" href="/YukiReflection/assets/changelog.html.fe56bfab.js"><link rel="prefetch" href="/YukiReflection/assets/contacts.html.8541ae79.js"><link rel="prefetch" href="/YukiReflection/assets/future.html.35497830.js"><link rel="prefetch" href="/YukiReflection/assets/features.html.fb2cff19.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.88a0631d.js"><link rel="prefetch" href="/YukiReflection/assets/api-example.html.450e2b7a.js"><link rel="prefetch" href="/YukiReflection/assets/api-exception.html.553960af.js"><link rel="prefetch" href="/YukiReflection/assets/home.html.87f49377.js"><link rel="prefetch" href="/YukiReflection/assets/quick-start.html.a8e6b073.js"><link rel="prefetch" href="/YukiReflection/assets/YukiReflection.html.3e0e5f98.js"><link rel="prefetch" href="/YukiReflection/assets/YukiReflection.html.6e8dfdd7.js"><link rel="prefetch" href="/YukiReflection/assets/CurrentClass.html.dc7279bd.js"><link rel="prefetch" href="/YukiReflection/assets/GenericClass.html.c797cc44.js"><link rel="prefetch" href="/YukiReflection/assets/VariousClass.html.9c666bf7.js"><link rel="prefetch" href="/YukiReflection/assets/ReflectionFactory.html.5be08357.js"><link rel="prefetch" href="/YukiReflection/assets/ReflectionFactory.html.a5559e9c.js"><link rel="prefetch" href="/YukiReflection/assets/DefinedTypeFactory.html.e642fe17.js"><link rel="prefetch" href="/YukiReflection/assets/ComponentTypeFactory.html.f040e23c.js"><link rel="prefetch" href="/YukiReflection/assets/GraphicsTypeFactory.html.2797253a.js"><link rel="prefetch" href="/YukiReflection/assets/ViewTypeFactory.html.9228d573.js"><link rel="prefetch" href="/YukiReflection/assets/VariableTypeFactory.html.0a0df340.js"><link rel="prefetch" href="/YukiReflection/assets/CurrentClass.html.a39c7c61.js"><link rel="prefetch" href="/YukiReflection/assets/GenericClass.html.ffdaf568.js"><link rel="prefetch" href="/YukiReflection/assets/VariousClass.html.36a38dcc.js"><link rel="prefetch" href="/YukiReflection/assets/DexClassFinder.html.f5efad4e.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorFinder.html.e59ecc69.js"><link rel="prefetch" href="/YukiReflection/assets/FieldFinder.html.b7011031.js"><link rel="prefetch" href="/YukiReflection/assets/MethodFinder.html.342c1fd7.js"><link rel="prefetch" href="/YukiReflection/assets/BaseFinder.html.812a050e.js"><link rel="prefetch" href="/YukiReflection/assets/VariableTypeFactory.html.7e8b800c.js"><link rel="prefetch" href="/YukiReflection/assets/DefinedTypeFactory.html.d798048a.js"><link rel="prefetch" href="/YukiReflection/assets/ComponentTypeFactory.html.7505e647.js"><link rel="prefetch" href="/YukiReflection/assets/GraphicsTypeFactory.html.8252c601.js"><link rel="prefetch" href="/YukiReflection/assets/ViewTypeFactory.html.2a07dc33.js"><link rel="prefetch" href="/YukiReflection/assets/BaseFinder.html.27357ff0.js"><link rel="prefetch" href="/YukiReflection/assets/DexClassFinder.html.d909f71f.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorFinder.html.15fe4612.js"><link rel="prefetch" href="/YukiReflection/assets/FieldFinder.html.c4ba046b.js"><link rel="prefetch" href="/YukiReflection/assets/MethodFinder.html.f92accf7.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorRules.html.d4ec4eae.js"><link rel="prefetch" href="/YukiReflection/assets/FieldRules.html.1bdd4f30.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRules.html.fd884aa2.js"><link rel="prefetch" href="/YukiReflection/assets/MethodRules.html.674801b6.js"><link rel="prefetch" href="/YukiReflection/assets/CountRules.html.0900393b.js"><link rel="prefetch" href="/YukiReflection/assets/ModifierRules.html.bd1880fe.js"><link rel="prefetch" href="/YukiReflection/assets/NameRules.html.35dc70b7.js"><link rel="prefetch" href="/YukiReflection/assets/ObjectRules.html.5e653f63.js"><link rel="prefetch" href="/YukiReflection/assets/CountRules.html.7bb05538.js"><link rel="prefetch" href="/YukiReflection/assets/ModifierRules.html.3bcf8e79.js"><link rel="prefetch" href="/YukiReflection/assets/NameRules.html.b078a177.js"><link rel="prefetch" href="/YukiReflection/assets/ObjectRules.html.faf0320c.js"><link rel="prefetch" href="/YukiReflection/assets/ConstructorRules.html.f10ebc65.js"><link rel="prefetch" href="/YukiReflection/assets/FieldRules.html.e23b2343.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRules.html.854655e5.js"><link rel="prefetch" href="/YukiReflection/assets/MethodRules.html.4f7471cd.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRulesResult.html.3eaa80e8.js"><link rel="prefetch" href="/YukiReflection/assets/MemberRulesResult.html.68563fb1.js"><link rel="prefetch" href="/YukiReflection/assets/404.html.5d5f90c0.js">
|
||
<link rel="stylesheet" href="/YukiReflection/assets/style.7c106af9.css">
|
||
</head>
|
||
<body>
|
||
<div id="app"><!--[--><div class="theme-container"><!--[--><header class="navbar"><div class="toggle-sidebar-button" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><div class="icon" aria-hidden="true"><span></span><span></span><span></span></div></div><span><a href="/YukiReflection/en/" class=""><img class="logo" src="/YukiReflection/images/logo.png" alt="Yuki Reflection"><span class="site-name can-hide">Yuki Reflection</span></a></span><div class="navbar-items-wrapper" style=""><!--[--><!--]--><nav class="navbar-items can-hide"><!--[--><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Navigation"><span class="title">Navigation</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Navigation"><span class="title">Navigation</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Get Started</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/guide/home" class="" aria-label="Introduce"><!--[--><!--]--> Introduce <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/guide/quick-start" class="" aria-label="Quick Start"><!--[--><!--]--> Quick Start <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Configs</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/config/api-example" class="" aria-label="API Basic Configs"><!--[--><!--]--> API Basic Configs <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/config/api-exception" class="" aria-label="API Exception Handling"><!--[--><!--]--> API Exception Handling <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>API Document</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/home" class="" aria-label="Document Introduction"><!--[--><!--]--> Document Introduction <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/YukiReflection" class="" aria-label="Public API"><!--[--><!--]--> Public API <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/features" class="router-link-active" aria-label="Features"><!--[--><!--]--> Features <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>About</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/changelog" class="" aria-label="Changelog"><!--[--><!--]--> Changelog <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/future" class="" aria-label="Looking for Future"><!--[--><!--]--> Looking for Future <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/contacts" class="" aria-label="Contact Us"><!--[--><!--]--> Contact Us <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/about" class="" aria-label="About this Document"><!--[--><!--]--> About this Document <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><a href="/YukiReflection/en/about/contacts" class="" aria-label="Contact Us"><!--[--><!--]--> Contact Us <!--[--><!--]--></a></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Select language"><span class="title">English (US)</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Select language"><span class="title">English (US)</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><a aria-current="page" href="/YukiReflection/en/api/features.html" class="router-link-active router-link-exact-active router-link-active" aria-label="English"><!--[--><!--]--> English <!--[--><!--]--></a></li><li class="navbar-dropdown-item"><a href="/YukiReflection/zh-cn/api/features.html" class="" aria-label="简体中文"><!--[--><!--]--> 简体中文 <!--[--><!--]--></a></li><!--]--></ul></div></div><div class="navbar-item"><a class="external-link" href="https://github.com/fankes/YukiReflection" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><button class="toggle-color-mode-button" title="toggle color mode"><svg style="" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M16 12.005a4 4 0 1 1-4 4a4.005 4.005 0 0 1 4-4m0-2a6 6 0 1 0 6 6a6 6 0 0 0-6-6z" fill="currentColor"></path><path d="M5.394 6.813l1.414-1.415l3.506 3.506L8.9 10.318z" fill="currentColor"></path><path d="M2 15.005h5v2H2z" fill="currentColor"></path><path d="M5.394 25.197L8.9 21.691l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 25.005h2v5h-2z" fill="currentColor"></path><path d="M21.687 23.106l1.414-1.415l3.506 3.506l-1.414 1.414z" fill="currentColor"></path><path d="M25 15.005h5v2h-5z" fill="currentColor"></path><path d="M21.687 8.904l3.506-3.506l1.414 1.415l-3.506 3.505z" fill="currentColor"></path><path d="M15 2.005h2v5h-2z" fill="currentColor"></path></svg><svg style="display:none;" class="icon" focusable="false" viewBox="0 0 32 32"><path d="M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z" fill="currentColor"></path></svg></button><form class="search-box" role="search"><input type="search" placeholder="Search" autocomplete="off" spellcheck="false" value><!----></form></div></header><!--]--><div class="sidebar-mask"></div><!--[--><aside class="sidebar"><nav class="navbar-items"><!--[--><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Navigation"><span class="title">Navigation</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Navigation"><span class="title">Navigation</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Get Started</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/guide/home" class="" aria-label="Introduce"><!--[--><!--]--> Introduce <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/guide/quick-start" class="" aria-label="Quick Start"><!--[--><!--]--> Quick Start <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>Configs</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/config/api-example" class="" aria-label="API Basic Configs"><!--[--><!--]--> API Basic Configs <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/config/api-exception" class="" aria-label="API Exception Handling"><!--[--><!--]--> API Exception Handling <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>API Document</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/home" class="" aria-label="Document Introduction"><!--[--><!--]--> Document Introduction <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/YukiReflection" class="" aria-label="Public API"><!--[--><!--]--> Public API <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/api/features" class="router-link-active" aria-label="Features"><!--[--><!--]--> Features <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><li class="navbar-dropdown-item"><!--[--><h4 class="navbar-dropdown-subtitle"><span>About</span></h4><ul class="navbar-dropdown-subitem-wrapper"><!--[--><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/changelog" class="" aria-label="Changelog"><!--[--><!--]--> Changelog <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/future" class="" aria-label="Looking for Future"><!--[--><!--]--> Looking for Future <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/contacts" class="" aria-label="Contact Us"><!--[--><!--]--> Contact Us <!--[--><!--]--></a></li><li class="navbar-dropdown-subitem"><a href="/YukiReflection/en/about/about" class="" aria-label="About this Document"><!--[--><!--]--> About this Document <!--[--><!--]--></a></li><!--]--></ul><!--]--></li><!--]--></ul></div></div><div class="navbar-item"><a href="/YukiReflection/en/about/contacts" class="" aria-label="Contact Us"><!--[--><!--]--> Contact Us <!--[--><!--]--></a></div><div class="navbar-item"><div class="navbar-dropdown-wrapper"><button class="navbar-dropdown-title" type="button" aria-label="Select language"><span class="title">English (US)</span><span class="arrow down"></span></button><button class="navbar-dropdown-title-mobile" type="button" aria-label="Select language"><span class="title">English (US)</span><span class="right arrow"></span></button><ul style="display:none;" class="navbar-dropdown"><!--[--><li class="navbar-dropdown-item"><a aria-current="page" href="/YukiReflection/en/api/features.html" class="router-link-active router-link-exact-active router-link-active" aria-label="English"><!--[--><!--]--> English <!--[--><!--]--></a></li><li class="navbar-dropdown-item"><a href="/YukiReflection/zh-cn/api/features.html" class="" aria-label="简体中文"><!--[--><!--]--> 简体中文 <!--[--><!--]--></a></li><!--]--></ul></div></div><div class="navbar-item"><a class="external-link" href="https://github.com/fankes/YukiReflection" rel="noopener noreferrer" target="_blank" aria-label="GitHub"><!--[--><!--]--> GitHub <span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!--[--><!--]--></a></div><!--]--></nav><!--[--><!--]--><ul class="sidebar-items"><!--[--><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">Get Started <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/YukiReflection/en/guide/home.html" class="sidebar-item" aria-label="Introduce"><!--[--><!--]--> Introduce <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/guide/quick-start.html" class="sidebar-item" aria-label="Quick Start"><!--[--><!--]--> Quick Start <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">Configs <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/YukiReflection/en/config/api-example.html" class="sidebar-item" aria-label="API Basic Configs"><!--[--><!--]--> API Basic Configs <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/config/api-exception.html" class="sidebar-item" aria-label="API Exception Handling"><!--[--><!--]--> API Exception Handling <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><p tabindex="0" class="sidebar-item sidebar-heading active collapsible">API Document <span class="down arrow"></span></p><ul style="" class="sidebar-item-children"><!--[--><li><a href="/YukiReflection/en/api/home.html" class="sidebar-item" aria-label="Document Introduce"><!--[--><!--]--> Document Introduce <!--[--><!--]--></a><!----></li><li><p tabindex="0" class="sidebar-item collapsible">Public API <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/YukiReflection.html" class="sidebar-item" aria-label="YukiReflection - object"><!--[--><!--]--> YukiReflection - object <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/type/android/ComponentTypeFactory.html" class="sidebar-item" aria-label="ComponentTypeFactory - kt"><!--[--><!--]--> ComponentTypeFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/type/android/GraphicsTypeFactory.html" class="sidebar-item" aria-label="GraphicsTypeFactory - kt"><!--[--><!--]--> GraphicsTypeFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/type/android/ViewTypeFactory.html" class="sidebar-item" aria-label="ViewTypeFactory - kt"><!--[--><!--]--> ViewTypeFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/type/java/VariableTypeFactory.html" class="sidebar-item" aria-label="VariableTypeFactory - kt"><!--[--><!--]--> VariableTypeFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/type/defined/DefinedTypeFactory.html" class="sidebar-item" aria-label="DefinedTypeFactory - kt"><!--[--><!--]--> DefinedTypeFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/factory/ReflectionFactory.html" class="sidebar-item" aria-label="ReflectionFactory - kt"><!--[--><!--]--> ReflectionFactory - kt <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/members/MethodFinder.html" class="sidebar-item" aria-label="MethodFinder - class"><!--[--><!--]--> MethodFinder - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder.html" class="sidebar-item" aria-label="ConstructorFinder - class"><!--[--><!--]--> ConstructorFinder - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/members/FieldFinder.html" class="sidebar-item" aria-label="FieldFinder - class"><!--[--><!--]--> FieldFinder - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/DexClassFinder.html" class="sidebar-item" aria-label="DexClassFinder - class"><!--[--><!--]--> DexClassFinder - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/rules/result/MemberRulesResult.html" class="sidebar-item" aria-label="MemberRulesResult - class"><!--[--><!--]--> MemberRulesResult - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/rules/MemberRules.html" class="sidebar-item" aria-label="MemberRules - class"><!--[--><!--]--> MemberRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/rules/FieldRules.html" class="sidebar-item" aria-label="FieldRules - class"><!--[--><!--]--> FieldRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/rules/MethodRules.html" class="sidebar-item" aria-label="MethodRules - class"><!--[--><!--]--> MethodRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/classes/rules/ConstructorRules.html" class="sidebar-item" aria-label="ConstructorRules - class"><!--[--><!--]--> ConstructorRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/base/BaseFinder.html" class="sidebar-item" aria-label="BaseFinder - class"><!--[--><!--]--> BaseFinder - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/base/rules/CountRules.html" class="sidebar-item" aria-label="CountRules - class"><!--[--><!--]--> CountRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/base/rules/ModifierRules.html" class="sidebar-item" aria-label="ModifierRules - class"><!--[--><!--]--> ModifierRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/base/rules/NameRules.html" class="sidebar-item" aria-label="NameRules - class"><!--[--><!--]--> NameRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/finder/base/rules/ObjectRules.html" class="sidebar-item" aria-label="ObjectRules - class"><!--[--><!--]--> ObjectRules - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/bean/VariousClass.html" class="sidebar-item" aria-label="VariousClass - class"><!--[--><!--]--> VariousClass - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/bean/CurrentClass.html" class="sidebar-item" aria-label="CurrentClass - class"><!--[--><!--]--> CurrentClass - class <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/api/public/com/highcapable/yukireflection/bean/GenericClass.html" class="sidebar-item" aria-label="GenericClass - class"><!--[--><!--]--> GenericClass - class <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html" class="router-link-active router-link-exact-active router-link-active sidebar-item active" aria-label="Features"><!--[--><!--]--> Features <!--[--><!--]--></a><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/YukiReflection/en/api/features.html#class-extensions" class="router-link-active router-link-exact-active sidebar-item" aria-label="Class Extensions"><!--[--><!--]--> Class Extensions <!--[--><!--]--></a><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/YukiReflection/en/api/features.html#object-conversion" class="router-link-active router-link-exact-active sidebar-item" aria-label="Object Conversion"><!--[--><!--]--> Object Conversion <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#existential-judgment" class="router-link-active router-link-exact-active sidebar-item" aria-label="Existential Judgment"><!--[--><!--]--> Existential Judgment <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#vague-search" class="router-link-active router-link-exact-active sidebar-item" aria-label="Vague Search"><!--[--><!--]--> Vague Search <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#member-extensions" class="router-link-active router-link-exact-active sidebar-item" aria-label="Member Extensions"><!--[--><!--]--> Member Extensions <!--[--><!--]--></a><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/YukiReflection/en/api/features.html#find-and-reflection" class="router-link-active router-link-exact-active sidebar-item" aria-label="Find and Reflection"><!--[--><!--]--> Find and Reflection <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#optional-find-conditions" class="router-link-active router-link-exact-active sidebar-item" aria-label="Optional Find Conditions"><!--[--><!--]--> Optional Find Conditions <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#find-in-super-class" class="router-link-active router-link-exact-active sidebar-item" aria-label="Find in Super Class"><!--[--><!--]--> Find in Super Class <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#vague-find" class="router-link-active router-link-exact-active sidebar-item" aria-label="Vague Find"><!--[--><!--]--> Vague Find <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#multiple-find" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multiple Find"><!--[--><!--]--> Multiple Find <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#static-bytecode" class="router-link-active router-link-exact-active sidebar-item" aria-label="Static Bytecode"><!--[--><!--]--> Static Bytecode <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#obfuscated-bytecode" class="router-link-active router-link-exact-active sidebar-item" aria-label="Obfuscated Bytecode"><!--[--><!--]--> Obfuscated Bytecode <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#directly-called" class="router-link-active router-link-exact-active sidebar-item" aria-label="Directly Called"><!--[--><!--]--> Directly Called <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#find-again" class="router-link-active router-link-exact-active sidebar-item" aria-label="Find Again"><!--[--><!--]--> Find Again <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#relative-matching" class="router-link-active router-link-exact-active sidebar-item" aria-label="Relative Matching"><!--[--><!--]--> Relative Matching <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#calling-generics" class="router-link-active router-link-exact-active sidebar-item" aria-label="Calling Generics"><!--[--><!--]--> Calling Generics <!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#pay-attention-of-trap" class="router-link-active router-link-exact-active sidebar-item" aria-label="Pay Attention of Trap"><!--[--><!--]--> Pay Attention of Trap <!--[--><!--]--></a><!----></li><!--]--></ul></li><li><a aria-current="page" href="/YukiReflection/en/api/features.html#common-type-extensions" class="router-link-active router-link-exact-active sidebar-item" aria-label="Common Type Extensions"><!--[--><!--]--> Common Type Extensions <!--[--><!--]--></a><!----></li><!--]--></ul></li><!--]--></ul></li><li><p tabindex="0" class="sidebar-item sidebar-heading collapsible">About <span class="right arrow"></span></p><ul style="display:none;" class="sidebar-item-children"><!--[--><li><a href="/YukiReflection/en/about/changelog.html" class="sidebar-item" aria-label="Changelog"><!--[--><!--]--> Changelog <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/about/future.html" class="sidebar-item" aria-label="Looking for Future"><!--[--><!--]--> Looking for Future <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/about/contacts.html" class="sidebar-item" aria-label="Contact Us"><!--[--><!--]--> Contact Us <!--[--><!--]--></a><!----></li><li><a href="/YukiReflection/en/about/about.html" class="sidebar-item" aria-label="About this Document"><!--[--><!--]--> About this Document <!--[--><!--]--></a><!----></li><!--]--></ul></li><!--]--></ul><!--[--><!--]--></aside><!--]--><!--[--><main class="page"><!--[--><!--]--><div class="theme-default-content"><!--[--><!--]--><div><h1 id="features" tabindex="-1"><a class="header-anchor" href="#features" aria-hidden="true">#</a> Features</h1><blockquote><p>This page contains usage examples for all core features of <code>YukiReflection</code>.</p></blockquote><h2 id="class-extensions" tabindex="-1"><a class="header-anchor" href="#class-extensions" aria-hidden="true">#</a> Class Extensions</h2><blockquote><p>Here are the extension functions related to the <strong>Class</strong> object itself.</p></blockquote><h3 id="object-conversion" tabindex="-1"><a class="header-anchor" href="#object-conversion" aria-hidden="true">#</a> Object Conversion</h3><p>Suppose we want to get a <code>Class</code> that cannot be called directly.</p><p>Normally, we can use the standard reflection API to find this <code>Class</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Class in the default ClassLoader environment</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;">.forName(</span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// Specify the Class in the ClassLoader environment</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> custom</span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;">.loadClass(</span><span style="color:#96D0FF;">"com.demo.Test"</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>This is probably not very friendly, and <code>YukiReflection</code> provides you with a syntactic sugar that can be used anywhere.</p><p>The above writing can be written as <code>YukiReflection</code> as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Get this Class directly</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClass()</span></span>
|
||
<span class="line"><span style="color:#768390;">// ClassLoader where the custom Class is located</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClass(customClassLoader)</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>If the current <code>Class</code> does not exist, using the above method will throw an exception.</p><p>If you are not sure whether the <code>Class</code> exists, you can refer to the following solutions.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Get this Class directly</span></span>
|
||
<span class="line"><span style="color:#768390;">// If not available, the result will be null but no exception will be thrown</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClassOrNull()</span></span>
|
||
<span class="line"><span style="color:#768390;">// ClassLoader where the custom Class is located</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#768390;">// If not available, the result will be null but no exception will be thrown</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClassOrNull(customClassLoader)</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>We can also get an existing <code>Class</code> object by mapping.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this Class can be obtained directly</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> classOf</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">Test</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// We can also customize the ClassLoader where the Class is located, which is very effective for stubs</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> classOf</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">Test</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;">(customClassLoader)</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 class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#classof-method">classOf</a>, <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#string-toclass-ext-method">String.toClass</a>, <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#string-toclassornull-ext-method">String.toClassOrNull</a> methods.</p></div><h3 id="existential-judgment" tabindex="-1"><a class="header-anchor" href="#existential-judgment" aria-hidden="true">#</a> Existential Judgment</h3><p>Suppose we want to determine whether a <code>Class</code> exists.</p><p>Usually, we can use the standard reflection API to find this <code>Class</code> to determine whether it exists by exception.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Class in the default ClassLoader environment</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">try</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Class</span><span style="color:#ADBAC7;">.forName(</span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">} </span><span style="color:#F47067;">catch</span><span style="color:#ADBAC7;"> (_</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#768390;">// Specify the Class in the ClassLoader environment</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">try</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> custom</span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;">.loadClass(</span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">true</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">} </span><span style="color:#F47067;">catch</span><span style="color:#ADBAC7;"> (_</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Throwable</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">false</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></div><p>This is probably not very friendly, and <code>YukiReflection</code> provides you with a syntactic sugar that can be used anywhere.</p><p>The above writing can be written as <code>YukiReflection</code> as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Check if this class exists</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.hasClass()</span></span>
|
||
<span class="line"><span style="color:#768390;">// ClassLoader where the custom Class is located</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F47067;">var</span><span style="color:#ADBAC7;"> isExist </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.hasClass(customClassLoader)</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 class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#string-hasclass-ext-method">String.hasClass</a> method.</p></div><h3 id="vague-search" tabindex="-1"><a class="header-anchor" href="#vague-search" aria-hidden="true">#</a> Vague Search <span class="badge tip" style="vertical-align:middle;"><!--[-->Beta<!--]--></span></h3><p>The <code>Class</code> name in the current app's <strong>Dex</strong> after being obfuscated by tools such as R8 will be difficult to distinguish.</p><p>Its correct position is uncertain, and cannot be obtained directly through <a href="#object-conversion">Object Conversion</a>.</p><p>At this point, there is <code>DexClassFinder</code>, its role is to determine the instance of this <code>Class</code> by the bytecode features in the <code>Class</code> that need to be searched.</p><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>At present, the function of <strong>DexClassFinder</strong> is still in the experimental stage.</p><p>Since the search function is only implemented through the Java layer, the performance may not reach the optimal level when there are too many current app's <strong>Class</strong>.</p><p>If something got wrong welcome to feedback.</p><p>Since it is a reflection-level API, currently it can only locate the specified <strong>Class</strong> through the characteristics of <strong>Class and Member</strong>, and cannot locate it by specifying the string and method content characteristics in the bytecode.</p><p>The speed of searching <strong>Class</strong> depends on the performance of the current device.</p><p>At present, the mainstream mobile processors are in the <strong>3~10s</strong> range when the conditions are not complicated in the <strong>10~15w</strong> number of <strong>Class</strong>, the fastest speed can reach within <strong>25s</strong> under slightly complex conditions.</p><p>Please note that the more the same type <strong>Class</strong> is matched, the slower the speed.</p></div><h4 id="get-started" tabindex="-1"><a class="header-anchor" href="#get-started" aria-hidden="true">#</a> Get Started</h4><p>Below is a simple usage example.</p><p>Suppose the following <code>Class</code> is what we want, the names are obfuscated and may be different in each version.</p><blockquote><p>The following example</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">a</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">extends</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">Activity</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">implements</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">Serializable</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;">a</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">var1</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:#F69D50;"> </span><span style="color:#ADBAC7;">a;</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:#F69D50;"> </span><span style="color:#ADBAC7;">b;</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;">a;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">protected</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">onCreate</span><span style="color:#ADBAC7;">(Bundle </span><span style="color:#F69D50;">var1</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;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">var1</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;">a</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">, String </span><span style="color:#F69D50;">var2</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;">a</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;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">a</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var1</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">a</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var2</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">b</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">var3</span><span style="color:#ADBAC7;">, String </span><span style="color:#F69D50;">var4</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><p>At this point, we want to get this <code>Class</code>, you can use the <code>ClassLoader.searchClass</code> method directly.</p><p>Each of the conditions demonstrated below is optional, and the more complex the conditions, the more accurate the positioning and the worse the performance.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">searchClass {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Start the search from the specified package name range</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// In actual use, you can specify multiple package name ranges at the same time</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> from(</span><span style="color:#96D0FF;">"com.demo"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the result of getSimpleName of the current Class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// You can directly make logical judgments on this string</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Here we are not sure whether its name is a, we can only judge the length of the string</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> simpleName { it.length </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the inherited parent class object</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// If it is an existing stub, it can be directly represented by generics</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> extends</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">Activity</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the inherited parent class object</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Which can be written directly as the full class name</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And you can also specify multiple objects at the same time</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> extends(</span><span style="color:#96D0FF;">"android.app.Activity"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the implemented interface</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// If it exists stub, can be directly represented by generics</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> implements</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">Serializable</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the implemented interface</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Which can be written directly as a full class name, or you can specify multiple at the same time</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> implements(</span><span style="color:#96D0FF;">"java.io.Serializable"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the constructor</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And the number count that exists in the current class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> { param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">) }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the variable</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And the number that exists in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field { type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the variable</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And the number that exists in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field { type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Directly specify the number of all variables that exist in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field().count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// If you think the number of variables is indeterminate</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// You can also use the following custom conditions</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field().count(</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">..</span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field().count { it </span><span style="color:#F47067;">>=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And the number that exists in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;">"onCreate"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BundleClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the modifier, and the number count in the current class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isStatic </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> isPrivate }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">UnitType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the modifier, and the number count in the current class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isPrivate </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#F47067;">not</span><span style="color:#ADBAC7;">() }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">StringClass</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the modifier, and the number count in the current class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isPrivate </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#F47067;">not</span><span style="color:#ADBAC7;">() }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">UnitType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Specify the type and style of the method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// As well as the modifier and VagueType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// And the number count that exists in the current class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isPrivate </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> isStatic.</span><span style="color:#F47067;">not</span><span style="color:#ADBAC7;">() }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">VagueType</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">VagueType</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">UnitType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Directly specify the number of all methods that exist in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method().count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// If you think the number of methods is uncertain, you can also use the following custom conditions</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method().count(</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">..</span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method().count { it </span><span style="color:#F47067;">>=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">5</span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Directly specify the number of all members existing in the current class count</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Members include: Field, Method, Constructor</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> member().count(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">9</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// There must be a static modifier in all members, you can add this condition like this</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> member {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isStatic }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get() </span><span style="color:#768390;">// Get the instance of this Class itself, if not found, it will return 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 class="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 class="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 class="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 class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>The conditional usage of <strong>Field</strong>, <strong>Method</strong>, <strong>Constructor</strong> in the above usage is consistent with the related usage in <a href="#member-extensions">Member Extensions</a>, with only minor differences.</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/classes/rules/MemberRules">MemberRules</a>, <a href="../api/public/com/highcapable/yukireflection/finder/classes/rules/FieldRules">FieldRules</a>, <a href="../api/public/com/highcapable/yukireflection/finder/classes/rules/MethodRules">MethodRules</a>, <a href="../api/public/com/highcapable/yukireflection/finder/classes/rules/ConstructorRules">ConstructorRules</a>.</p></div><h4 id="asynchronous-search" tabindex="-1"><a class="header-anchor" href="#asynchronous-search" aria-hidden="true">#</a> Asynchronous Search</h4><p>By default, <code>DexClassFinder</code> will use synchronous mode to search <code>Class</code>, which will block the current thread until it finds or finds an exception.</p><p>If the search takes too long, it may cause <strong>ANR</strong> problems to the current app.</p><p>In response to the above problems, we can enable asynchronous, just add the parameter <code>async = true</code>, which will not require you to start a thread again, the API has already handled the related problems for you.</p><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>To use this function, you need to pass in the <strong>Context</strong> of the current app as the first method parameter.</p><p>For the asynchronous case you need to use the <strong>wait</strong> method to get the result, the <strong>get</strong> method will no longer work.</p></div><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume this is the Context of the current app</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass(context, async </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 style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.wait { class1 </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get asynchronous result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass(context, async </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 style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.wait { class2 </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get asynchronous result</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></div><p>In this way, our search process runs asynchronously, it will not block the main thread, and each search will be performed in a separate thread at the same time, which can achieve the effect of parallel tasks.</p><h4 id="local-cache" tabindex="-1"><a class="header-anchor" href="#local-cache" aria-hidden="true">#</a> Local Cache</h4><p>Since the search is performed again every time the current app is reopened, this is a waste of repetitive performance when the current app's version is unchanged.</p><p>At this point, we can locally cache the search results of the current app's version by specifying the <code>name</code> parameter.</p><p>Next time, the found class name will be directly read from the local cache.</p><p>The local cache uses <code>SharedPreferences</code>, which will be saved to the app's data directory and will be re-cached after the app's version is updated.</p><p>After enabling the local cache, <code>async = true</code> will be set at the same time, you don't need to set it manually.</p><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>To use this function, you need to pass in the <strong>Context</strong> of the current app as the first method parameter.</p></div><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume this is the Context of the current app</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass(context, name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.class1"</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;">}.wait { class1 </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get asynchronous result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass(context, name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.class2"</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;">}.wait { class2 </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get asynchronous result</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></div><p>If you want to clear the local cache manually, you can use the following method to clear the current version of the current app's cache.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume this is the Context of the current app</span></span>
|
||
<span class="line"><span style="color:#F69D50;">DexClassFinder</span><span style="color:#ADBAC7;">.clearCache(context)</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></div><p>You can also clear the app's cache for a specific version.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume this is the Context of the current app</span></span>
|
||
<span class="line"><span style="color:#F69D50;">DexClassFinder</span><span style="color:#ADBAC7;">.clearCache(context, versionName </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"1.0"</span><span style="color:#ADBAC7;">, versionCode </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</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></div><h4 id="multiple-search" tabindex="-1"><a class="header-anchor" href="#multiple-search" aria-hidden="true">#</a> Multiple Search</h4><p>If you need to search a set of <code>Class</code> at the same time using a fixed condition, then you only need to use the <code>all</code> or <code>waitAll</code> method to get the result.</p><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Synchronous search, use all to get all the results found by the conditions</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.all().forEach { clazz </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get each result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#768390;">// Synchronous search, using all { ... } to iterate over each result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.all { clazz </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get each result</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"><span style="color:#768390;">// Asynchronous search, use waitAll to get all the results found by the conditions</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> context</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Context</span><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Assume this is the Context of the current app</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">searchClass(context, async </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 style="color:#768390;">// ...</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.waitAll { classes </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> classes.forEach {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get each result</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><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#classloader-searchclass-ext-method">ClassLoader.searchClass</a> method.</p></div><h2 id="member-extensions" tabindex="-1"><a class="header-anchor" href="#member-extensions" aria-hidden="true">#</a> Member Extensions</h2><blockquote><p>Here are the extension functions related to the <strong>Class</strong> bytecode member variables <strong>Field</strong>, <strong>Method</strong>, <strong>Constructor</strong>.</p></blockquote><div class="custom-container tip"><p class="custom-container-title">Tips</p><p><strong>Member</strong> is the interface description object of <strong>Field</strong>, <strong>Method</strong>, <strong>Constructor</strong>, which is the general term for the bytecode members in <strong>Class</strong> in Java reflection.</p></div><p>Suppose there is such a <code>Class</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">BaseTest</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isInit</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 ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">public</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;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">Test</span><span style="color:#ADBAC7;">(</span><span style="color:#F47067;">boolean</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">isInit</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;"> BaseTest</span><span style="color:#F69D50;"> </span><span style="color:#ADBAC7;">baseInstance;</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:#F69D50;"> </span><span style="color:#ADBAC7;">a;</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;">a;</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;">static</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">init</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;">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>
|
||
<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;">b</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;">b</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">a</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><h3 id="find-and-reflection" tabindex="-1"><a class="header-anchor" href="#find-and-reflection" aria-hidden="true">#</a> Find and Reflection</h3><p>Suppose we want to get the <code>doTask</code> method of <code>Test</code> and execute it.</p><p>Normally, we can use the standard reflection API to find this method.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using reflection API</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .getDeclaredMethod(</span><span style="color:#96D0FF;">"doTask"</span><span style="color:#ADBAC7;">, String::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#6CB6FF;">apply</span><span style="color:#ADBAC7;"> { isAccessible </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;"> .invoke(instance, </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>This is probably not very friendly, and <code>YukiReflection</code> provides you with a syntactic sugar that can be used anywhere.</p><p>The above writing can be written as <code>YukiReflection</code> as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more features, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder">MethodFinder</a>.</p></div><p>Similarly, we need to get the <code>isTaskRunning</code> field can also be written as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.field {</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;"> </span><span style="color:#F69D50;">BooleanType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).any() </span><span style="color:#768390;">// Any instantiates an object of any type of Field</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><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more features, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder">FieldFinder</a>.</p></div><p>Maybe you also want to get the current <code>Class</code> constructor, the same can be achieved.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// Can create a new instance</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>If you want to get the no-argument constructor of <code>Class</code>, you can write it as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;">().get().call() </span><span style="color:#768390;">// Create a new instance</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more features, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder">ConstructorFinder</a>.</p></div><h3 id="optional-find-conditions" tabindex="-1"><a class="header-anchor" href="#optional-find-conditions" aria-hidden="true">#</a> Optional Find Conditions</h3><p>Suppose we want to get the <code>getName</code> method in <code>Class</code>, which can be implemented as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"getName"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">StringClass</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).string() </span><span style="color:#768390;">// Get the result of the method</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>Through observation, it is found that there is only one method named <code>getName</code> in this <code>Class</code>, so can we make it simpler?</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"getName"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).string() </span><span style="color:#768390;">// Get the result of the method</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>Yes, you can refine your find criteria for methods that do not change exactly.</p><p>When using only <code>get</code> or <code>wait</code> methods to get results, <code>YukiReflection</code> <strong>will match the first found result in bytecode order</strong> by default.</p><p>The problem comes again, this <code>Class</code> has a <code>release</code> method, but its method parameters are very long, and some types may not be directly available.</p><p>Normally we would use <code>param(...)</code> to find this method, but is there an easier way.</p><p>At this point, after determining the uniqueness of the method, you can use <code>paramCount</code> to find the method.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">// At this point</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// We don't have to determine the specific type of method parameters, just write the number</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> paramCount </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance) </span><span style="color:#768390;">// Get this method</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>Although the above example can be successfully matched, it is not accurate.</p><p>At this time, you can also use <code>VagueType</code> to fill in the method parameter type that you do not want to fill in.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">// Use VagueType to fill in the type you don't want to fill in</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// While ensuring that other types can match</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">VagueType</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance) </span><span style="color:#768390;">// Get this method</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>If you are not sure about the type of each parameter, you can create a conditional method body with the <code>param { ... }</code> method.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">// Get the it (Class) method parameter type array instance</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// To only determine the known type and its position</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param { it[</span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">] </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> it[</span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">] </span><span style="color:#F47067;">==</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance) </span><span style="color:#768390;">// Get this method</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>Use <strong>param { ... }</strong> to create a conditional method body, where the variable <strong>it</strong> is the <strong>Class</strong> type array instance of the current method parameter, and you can freely use <strong>Class</strong> all objects and their methods in.</p><p>The condition at the end of the method body needs to return a <strong>Boolean</strong>, which is the final condition judgment result.</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder#type-method-1">FieldFinder.type</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#param-method-1">MethodFinder.param</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#returntype-method-1">MethodFinder.returnType</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder#param-method-1">ConstructorFinder.param</a> method.</p></div><h3 id="find-in-super-class" tabindex="-1"><a class="header-anchor" href="#find-in-super-class" aria-hidden="true">#</a> Find in Super Class</h3><p>You will notice that <code>Test</code> extends <code>BaseTest</code>, now we want to get the <code>doBaseTask</code> method of <code>BaseTest</code>, how do we do it without knowing the name of the super class?</p><p>Referring to the above find conditions, we only need to add a <code>superClass</code> to the find conditions to achieve this function.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Just add this condition</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> superClass()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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>At this time, we can get this method in the super class.</p><p><code>superClass</code> has a parameter <code>isOnlySuperClass</code>, when set to <code>true</code>, you can skip the current <code>Class</code> and only find the super class of the current <code>Class</code>.</p><p>Since we now know that the <code>doBaseTask</code> method only exists in the super class, this condition can be added to save finding time.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Add a find condition</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> superClass(isOnlySuperClass </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;">}.get(instance).call(</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>At this time, we can also get this method in the super class.</p><p>Once <code>superClass</code> is set, it will automatically cycle backward to find out whether this method exists in all extends super classes, until it finds that the target has no super class (the extends is <code>java.lang.Object</code>).</p><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#superclass-method">MethodFinder.superClass</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder#superclass-method">ConstructorFinder.superClass</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder#superclass-method">FieldFinder.superClass</a> methods.</p></div><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>The currently founded <strong>Method</strong> can only find the <strong>Method</strong> of the current <strong>Class</strong> unless the <strong>superClass</strong> condition is specified, which is the default behavior of the Java Reflection API.</p></div><h3 id="vague-find" tabindex="-1"><a class="header-anchor" href="#vague-find" aria-hidden="true">#</a> Vague Find</h3><p>If we want to find a method name, but are not sure if it has changed in each release, we can use vague find.</p><p>Suppose we want to get the <code>doTask</code> method in <code>Class</code>, which can be implemented as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Set name is case insensitive</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.equals(</span><span style="color:#96D0FF;">"dotask"</span><span style="color:#ADBAC7;">, isIgnoreCase </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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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>Knowing that there is currently only one <code>doTask</code> method in <code>Class</code>, we can also judge that the method name contains only the characters specified in it.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Only contains oTas</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.contains(</span><span style="color:#96D0FF;">"oTas"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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>We can also judge based on the first and last strings.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Contains do at the beginning and Task at the end</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.startsWith(</span><span style="color:#96D0FF;">"do"</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> it.endsWith(</span><span style="color:#96D0FF;">"Task"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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>By observing that this method name contains only letters, we can add a precise search condition.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> name {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Start with do, end with Task, just letters</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> it.startsWith(</span><span style="color:#96D0FF;">"do"</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> it.endsWith(</span><span style="color:#96D0FF;">"Task"</span><span style="color:#ADBAC7;">) </span><span style="color:#F47067;">&&</span><span style="color:#ADBAC7;"> it.isOnlyLetters()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</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><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>Use <strong>name { ... }</strong> to create a conditional method body, where the variable <strong>it</strong> is the string of the current name, and you can freely use it in the extension method of <strong>NameRules</strong> function.</p><p>The condition at the end of the method body needs to return a <strong>Boolean</strong>, which is the final condition judgment result.</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder#name-method-1">FieldFinder.name</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#name-method-1">MethodFinder.name</a> methods and <a href="../api/public/com/highcapable/yukireflection/finder/base/rules/NameRules">NameRules</a>.</p></div><h3 id="multiple-find" tabindex="-1"><a class="header-anchor" href="#multiple-find" aria-hidden="true">#</a> Multiple Find</h3><p>Sometimes, we may need to find a set of methods, constructors, and fields with the same characteristics in a <code>Class</code>.</p><p>At this time, we can use relative condition matching to complete.</p><p>Based on the result of the find condition, we only need to replace <code>get</code> with <code>all</code> to get all the bytecodes that match the condition.</p><p>Suppose this time we want to get all methods in <code>Class</code> with the number of method parameters in the range <code>1..3</code>, you can use the following implementation.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> paramCount(</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">..</span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.all(instance).forEach { instance </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Call and execute each method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> instance.call(...)</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></div><p>The above example can be perfectly matched to the following 3 methods.</p><p><code>private void doTask(String taskName)</code></p><p><code>private void release(String taskName, Function<boolean, String> task, boolean isFinish)</code></p><p><code>private void b(String a)</code></p><p>If you want to define the conditions for the range of the number of parameters more freely, you can use the following implementation.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> paramCount { it </span><span style="color:#F47067;"><</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">3</span><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.all(instance).forEach { instance </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Call and execute each method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> instance.call(...)</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></div><p>The above example can be perfectly matched to the following 6 methods.</p><p><code>private static void init()</code></p><p><code>private void doTask(String taskName)</code></p><p><code>private void stop(String a)</code></p><p><code>private void getName(String a)</code></p><p><code>private void b()</code></p><p><code>private void b(String a)</code></p><p>By observing that there are two methods named <code>b</code> in <code>Class</code>, you can use the following implementation.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"b"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.all(instance).forEach { instance </span><span style="color:#F47067;">-></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Call and execute each method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> instance.call(...)</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></div><p>The above example can be perfectly matched to the following 2 methods.</p><p><code>private void b()</code></p><p><code>private void b(String a)</code></p><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>Use <strong>paramCount { ... }</strong> to create a conditional method body, where the variable <strong>it</strong> is the integer of the current number of parameters, and you can use it freely in the extension method of <strong>CountRules</strong> function in it.</p><p>The condition at the end of the method body needs to return a <strong>Boolean</strong>, which is the final condition judgment result.</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#paramcount-method-2">MethodFinder.paramCount</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder#paramcount-method-2">ConstructorFinder.paramCount</a> methods and <a href="../api/public/com/highcapable/yukireflection/finder/base/rules/CountRules">CountRules</a>.</p></div><h3 id="static-bytecode" tabindex="-1"><a class="header-anchor" href="#static-bytecode" aria-hidden="true">#</a> Static Bytecode</h3><p>Some methods and fields are statically implemented in <code>Class</code>, at this time, we can call them without passing in an instance.</p><p>Suppose we want to get the contents of the static field <code>TAG</code> this time.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.field {</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;"> </span><span style="color:#F69D50;">StringClass</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().string() </span><span style="color:#768390;">// The type of Field is string and can be cast directly</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>Assuming that there is a non-static <code>TAG</code> field with the same name in <code>Class</code>, what should I do at this time?</p><p>Just add a filter.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.field {</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;"> </span><span style="color:#F69D50;">StringClass</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// This field to identify the lookup needs to be static</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isStatic }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().string() </span><span style="color:#768390;">// The type of Field is string and can be cast directly</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>We can also call a static method called <code>init</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"init"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call()</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>Likewise, you can identify it as a static.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"init"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// This method of identity find needs to be static</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> modifiers { isStatic }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call()</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 class="custom-container tip"><p class="custom-container-title">Tips</p><p>Use <strong>modifiers { ... }</strong> to create a conditional method body, at which point you can freely use its functionality in <strong>ModifierRules</strong>.</p><p>The condition at the end of the method body needs to return a <strong>Boolean</strong>, which is the final condition judgment result.</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder#modifiers-method">FieldFinder.modifiers</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#modifiers-method">MethodFinder.modifiers</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder#modifiers-method">ConstructorFinder.modifiers</a> methods and <a href="../api/public/com/highcapable/yukireflection/finder/base/rules/ModifierRules">ModifierRules</a>.</p></div><h3 id="obfuscated-bytecode" tabindex="-1"><a class="header-anchor" href="#obfuscated-bytecode" aria-hidden="true">#</a> Obfuscated Bytecode</h3><p>You may have noticed that the example <code>Class</code> given here has two obfuscated field names, both of which are <code>a</code>, how do we get them at this time?</p><p>There are two options.</p><p>The first option is to determine the name and type of the field.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.field {</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;">"a"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).any() </span><span style="color:#768390;">// Get a field named a with type Boolean</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>The second option is to determine where the type of the field is located.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.field {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">).index().first()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).any() </span><span style="color:#768390;">// Get the first field of type Boolean</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>In the above two cases, the corresponding field <code>private boolean a</code> can be obtained.</p><p>Likewise, there are two obfuscated method names in this <code>Class</code>, both of which are <code>b</code>.</p><p>You can also have two options to get them.</p><p>The first option is to determine the method name and method parameters.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"b"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</span><span style="color:#96D0FF;">"test_string"</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// Get the method whose name is b and whose parameter is [String]</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>The second option is to determine where the parameters of the method are located.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">).index().first()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</span><span style="color:#96D0FF;">"test_string"</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// Get the method whose first method parameter is [String]</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>Since it is observed that this method is last in <code>Class</code>, then we have an alternative.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> order().index().last()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get(instance).call(</span><span style="color:#96D0FF;">"test_string"</span><span style="color:#ADBAC7;">) </span><span style="color:#768390;">// Get the last method of the current Class</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div 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">Notice</p><p>Please try to avoid using <strong>order</strong> to filter bytecode subscripts, they may be indeterminate unless you are sure that its position in this <strong>Class</strong> must not change.</p></div><h3 id="directly-called" tabindex="-1"><a class="header-anchor" href="#directly-called" aria-hidden="true">#</a> Directly Called</h3><p>The methods of calling bytecode described above all need to use <code>get(instance)</code> to call the corresponding method.</p><p>Is there a simpler way?</p><p>At this point, you can use the <code>current</code> method on any instance to create a call space.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Assume this Class is not directly available</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Execute the doTask method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</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;">// Execute the stop method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;">"stop"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get name</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> method { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"getName"</span><span style="color:#ADBAC7;"> }.string()</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>We can also use <code>superClass</code> to call methods of the current <code>Class</code> super class.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Assume this Class is not directly available</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Execute the doBaseTask method of the parent class</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> superClass().method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</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></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>If you don't like to use a lambda to create the namespace of the current instance, you can use the <code>current()</code> method directly.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assuming this is an instance of this Class, this Class cannot be obtained directly</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Execute the doTask method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .current()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</span><span style="color:#96D0FF;">"task_name"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#768390;">// Execute the stop method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .current()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .method {</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;">"stop"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Get name</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> instance.current().method { name </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"getName"</span><span style="color:#ADBAC7;"> }.string()</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></div><p>Likewise, consecutive calls can be made between them, but <u><strong>inline calls are not allowed</strong></u>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Assume this Class is not directly available</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</span><span style="color:#96D0FF;">"task_name"</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.current()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .method {</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;">"stop"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call()</span></span>
|
||
<span class="line"><span style="color:#768390;">// ❗ Note that because current() returns the CurrentClass object itself</span></span>
|
||
<span class="line"><span style="color:#768390;">// It CANNOT BE CALLED like the following</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance.current().current()</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></div><p>For <code>Field</code> instances, there is also a convenience method that can directly get the object of the instance where <code>Field</code> is located.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Assume this Class is not directly available</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">instance.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// <Plan 1></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field {</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;">"baseInstance"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</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 style="color:#768390;">// <Plan 2></span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> field {</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;">"baseInstance"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.current()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> ?.method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }?.call(</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></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><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>The above <strong>current</strong> method is equivalent to calling the <strong>field { ... }.any()?.current()</strong> method in <strong>CurrentClass</strong> for you.</p><p>If there is no <strong>CurrentClass</strong> calling field, you need to use <strong>field { ... }.get(instance).current()</strong> to call it.</p></div><p>The problem comes again, I want to use reflection to create the following instance and call the method in it, how to do it?</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">).doTask(</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></div><p>Usually, we can use the standard reflection API to call.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClass()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .getDeclaredConstructor(Boolean::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#6CB6FF;">apply</span><span style="color:#ADBAC7;"> { isAccessible </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;"> .newInstance(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#6CB6FF;">apply</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> javaClass</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .getDeclaredMethod(</span><span style="color:#96D0FF;">"doTask"</span><span style="color:#ADBAC7;">, String::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> .</span><span style="color:#6CB6FF;">apply</span><span style="color:#ADBAC7;"> { isAccessible </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;"> .invoke(</span><span style="color:#6CB6FF;">this</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></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>But I feel that this approach is very troublesome.</p><p>Is there a more concise way to call it?</p><p>At this time, we can also use the <code>buildOf</code> method to create an instance.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#96D0FF;">"com.demo.Test"</span><span style="color:#ADBAC7;">.toClass().buildOf(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) { param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">) }?.current {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.call(</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></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>If you want the <code>buildOf</code> method to return the type of the current instance, you can include a type-generic declaration in it instead of using <code>as</code> to <code>cast</code> the target type.</p><p>In this case, the constructor of the instance itself is private, but the method inside is public, so we only need to create its constructor by reflection.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this Class can be obtained directly</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> test </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.buildOf</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">Test</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;">(</span><span style="color:#6CB6FF;">true</span><span style="color:#ADBAC7;">) { param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">) }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">test.doTask(</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></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/bean/CurrentClass">CurrentClass</a> and <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#class-buildof-ext-method">Class.buildOf</a> method.</p></div><h3 id="find-again" tabindex="-1"><a class="header-anchor" href="#find-again" aria-hidden="true">#</a> Find Again</h3><p>Suppose there are three different versions of <code>Class</code>, all of which are the same <code>Class</code> for different versions of this app.</p><p>There is also a method <code>doTask</code> in it, assuming they function the same.</p><blockquote><p>The following example of version A</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">Test</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;">doTask</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><blockquote><p>The following example of version B</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">Test</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;">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 style="color:#ADBAC7;">}</span></span>
|
||
<span class="line"></span></code></pre></div><blockquote><p>The following example of version C</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">Test</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;">doTask</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">taskName</span><span style="color:#ADBAC7;">, </span><span style="color:#F47067;">int</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">type</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><p>We need to get this same functionality of the <code>doTask</code> method in a different version, how do we do it?</p><p>At this point, you can use <code>RemedyPlan</code> to complete your needs.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.remedys {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.onFind {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Found logic can be implemented here</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> param(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">IntType</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.onFind {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Found logic can be implemented here</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.wait(instance) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the result of the method</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></div><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>The method lookup result using <strong>RemedyPlan</strong> can no longer use <strong>get</strong> to get method instance, you should use <strong>wait</strong> method.</p></div><p>Also, you can continue to use <code>RemedyPlan</code> while using <a href="#multiple-find">Multiple Find</a>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is an instance of this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> instance </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Call and execute using YukiReflection</span></span>
|
||
<span class="line"><span style="color:#F69D50;">Test</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.remedys {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> paramCount(</span><span style="color:#6CB6FF;">0</span><span style="color:#ADBAC7;">..</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.onFind {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Found logic can be implemented here</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> method {</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;"> paramCount(</span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">..</span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }.onFind {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Found logic can be implemented here</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> }</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.waitAll(instance) {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the result of the method</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></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/finder/members/MethodFinder#remedyplan-class">MethodFinder.RemedyPlan</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/ConstructorFinder#remedyplan-class">ConstructorFinder.RemedyPlan</a>, <a href="../api/public/com/highcapable/yukireflection/finder/members/FieldFinder#remedyplan-class">FieldFinder.RemedyPlan</a> .</p></div><h3 id="relative-matching" tabindex="-1"><a class="header-anchor" href="#relative-matching" aria-hidden="true">#</a> Relative Matching</h3><p>Suppose there is a <code>Class</code> with the same function in different versions of the current app but only the name of the <code>Class</code> is different.</p><blockquote><p>The following example of version A</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">ATest</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;">doTask</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><blockquote><p>The following example of version B</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">BTest</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;">doTask</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><p>At this time, what should we do if we want to call the <code>doTask</code> method in this <code>Class</code> in each version?</p><p>The usual practice is to check if <code>Class</code> exists.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// First find this Class</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> currentClass </span><span style="color:#F47067;">=</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">if</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.demo.ATest"</span><span style="color:#ADBAC7;">.hasClass()) </span><span style="color:#96D0FF;">"com.demo.ATest"</span><span style="color:#ADBAC7;">.toClass() </span><span style="color:#F47067;">else</span><span style="color:#ADBAC7;"> </span><span style="color:#96D0FF;">"com.demo.BTest"</span><span style="color:#ADBAC7;">.toClass()</span></span>
|
||
<span class="line"><span style="color:#768390;">// Then look for this method and call</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">currentClass.method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call()</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>I feel that this solution is very inelegant and cumbersome, then <code>YukiReflection</code> provides you with a very convenient <code>VariousClass</code> to solve this problem.</p><p>Now, you can get this <code>Class</code> directly using the following methods.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.demo.ATest"</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">"com.demo.BTest"</span><span style="color:#ADBAC7;">).get().method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call()</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>If the current <code>Class</code> exists in the specified <code>ClassLoader</code>, you can fill in your <code>ClassLoader</code> in <code>get</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F69D50;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.demo.ATest"</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">"com.demo.BTest"</span><span style="color:#ADBAC7;">).get(customClassLoader).method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().call()</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>If you are not sure that all <code>Class</code> will be matched, you can use the <code>getOrNull</code> method.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> customClassLoader</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">ClassLoader?</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ... </span><span style="color:#768390;">// Assume this is your ClassLoader</span></span>
|
||
<span class="line"><span style="color:#F69D50;">VariousClass</span><span style="color:#ADBAC7;">(</span><span style="color:#96D0FF;">"com.demo.ATest"</span><span style="color:#ADBAC7;">, </span><span style="color:#96D0FF;">"com.demo.BTest"</span><span style="color:#ADBAC7;">).getOrNull(customClassLoader)?.method {</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;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}?.get()?.call()</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 class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/bean/VariousClass">VariousClass</a>.</p></div><h3 id="calling-generics" tabindex="-1"><a class="header-anchor" href="#calling-generics" aria-hidden="true">#</a> Calling Generics</h3><p>In the process of reflection, we may encounter generic problems.</p><p>In the reflection processing of generics, <code>YukiReflection</code> also provides a syntactic sugar that can be used anywhere.</p><p>For example we have the following generic class.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestGeneric</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">R</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;"> (t</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, r</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</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>When we want to get a <code>Class</code> instance of the generic <code>T</code> or <code>R</code> in the current <code>Class</code>, only the following implementation is required.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TestGeneric</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, </span><span style="color:#F69D50;">R</span><span style="color:#F47067;">></span><span style="color:#ADBAC7;"> (t</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">T</span><span style="color:#ADBAC7;">, r</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">R</span><span style="color:#ADBAC7;">) {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</span><span style="color:#ADBAC7;">() {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the operation object of the current instance</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the Class instance of T, in the 0th position of the parameter</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// The default value can not be written</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> current().generic()?.argument()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the Class instance of R, in parameter 1</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> rClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> current().generic()?.argument(index </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// You can also use the following syntax</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> current().generic {</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the Class instance of T</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// In the 0th position of the parameter, the default value can be left blank</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> argument()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// Get the Class instance of R, in parameter 1</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> rClass </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> argument(index </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</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 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>When we want to call this <code>Class</code> externally, it can be implemented as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#768390;">// Assume this is the Class of T</span></span>
|
||
<span class="line"><span style="color:#F47067;">class</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TI</span><span style="color:#ADBAC7;"> {</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">fun</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</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 style="color:#768390;">// Assume this is an instance of T</span></span>
|
||
<span class="line"><span style="color:#F47067;">val</span><span style="color:#ADBAC7;"> tInstance</span><span style="color:#F47067;">:</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">TI</span><span style="color:#ADBAC7;">? </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> ...</span></span>
|
||
<span class="line"><span style="color:#768390;">// Get the Class instance of T</span></span>
|
||
<span class="line"><span style="color:#768390;">// In the 0th position of the parameter, the default value can be left blank</span></span>
|
||
<span class="line"><span style="color:#768390;">// And get the method foo and call it</span></span>
|
||
<span class="line"><span style="color:#F69D50;">TestGeneric</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.generic()?.argument()?.method {</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;">"foo"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}?.get(tInstance)?.invoke</span><span style="color:#F47067;"><</span><span style="color:#F69D50;">TI</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 class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more functions, please refer to <a href="../api/public/com/highcapable/yukireflection/bean/CurrentClass#generic-method">CurrentClass.generic</a>, <a href="../api/public/com/highcapable/yukireflection/factory/ReflectionFactory#class-generic-ext-method">Class.generic</a> methods and <a href="../api/public/com/highcapable/yukireflection/bean/GenericClass">GenericClass</a>.</p></div><h3 id="pay-attention-of-trap" tabindex="-1"><a class="header-anchor" href="#pay-attention-of-trap" aria-hidden="true">#</a> Pay Attention of Trap</h3><blockquote><p>Here are some misunderstandings that may be encountered during use for reference.</p></blockquote><h4 id="restrictive-find-conditions" tabindex="-1"><a class="header-anchor" href="#restrictive-find-conditions" aria-hidden="true">#</a> Restrictive Find Conditions</h4><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>In find conditions you can only use <strong>index</strong> function once except <strong>order</strong>.</p></div><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">method {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">).index(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ❗ Wrong usage, please keep only one index method</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> returnType(</span><span style="color:#F69D50;">StringClass</span><span style="color:#ADBAC7;">).index(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><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>The following find conditions can be used without any problems.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">method {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> param(</span><span style="color:#F69D50;">BooleanType</span><span style="color:#ADBAC7;">).index(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">2</span><span style="color:#ADBAC7;">)</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> order().index(num </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">1</span><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></div><h4 id="necessary-find-conditions" tabindex="-1"><a class="header-anchor" href="#necessary-find-conditions" aria-hidden="true">#</a> Necessary Find Conditions</h4><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>In common method find conditions, <u><strong>even methods without parameters need to set find conditions</strong></u>.</p></div><p>Suppose we have the following <code>Class</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">TestFoo</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;">foo</span><span style="color:#ADBAC7;">(String </span><span style="color:#F69D50;">string</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;">public</span><span style="color:#ADBAC7;"> </span><span style="color:#F47067;">void</span><span style="color:#ADBAC7;"> </span><span style="color:#DCBDFB;">foo</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><p>We want to get the <code>public void foo()</code> method, which can be written as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"foo"</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></div><p>However, the above example <u><strong>is wrong</strong></u>.</p><p>You will find two <code>foo</code> methods in this <code>Class</code>, one of which takes a method parameter.</p><p>Since the above example does not set the find conditions for <code>param</code>, the result will be the first method <code>public void foo(String string)</code> that matches the name and matches the bytecode order, not the last method we need.</p><p>This is a <strong>frequent error</strong>, <strong>without method parameters, you will lose the use of method parameter find conditions</strong>.</p><p>The correct usage is as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.method {</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;">"foo"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> </span><span style="color:#768390;">// ✅ Correct usage, add detailed filter conditions</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> emptyParam()</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></div><p>At this point, the above example will perfectly match the <code>public void foo()</code> method.</p><h4 id="abbreviated-find-conditions" tabindex="-1"><a class="header-anchor" href="#abbreviated-find-conditions" aria-hidden="true">#</a> Abbreviated Find Conditions</h4><blockquote><p>In the construction method find conditions, <u><strong>constructors without parameters do not need to fill in the find conditions</strong></u>.</p></blockquote><p>Suppose we have the following <code>Class</code>.</p><blockquote><p>The following example</p></blockquote><div class="language-java ext-java"><pre class="shiki" style="background-color:#22272e;"><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;">TestFoo</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;">TestFoo</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><p>We want to get the <code>public TestFoo()</code> constructor, which can be written as follows.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</span><span style="color:#ADBAC7;"> { emptyParam() }</span></span>
|
||
<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>The above example can successfully obtain the <code>public TestFoo()</code> constructor, but it feels a bit cumbersome.</p><p>Unlike normal methods, since the constructor does not need to consider the <code>name</code>, when the constructor has no parameters, we can omit the <code>emptyParam</code> parameter.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#F69D50;">TestFoo</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.java.</span><span style="color:#DCBDFB;">constructor</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><h4 id="bytecode-type" tabindex="-1"><a class="header-anchor" href="#bytecode-type" aria-hidden="true">#</a> Bytecode Type</h4><div class="custom-container danger"><p class="custom-container-title">Pay Attention</p><p>In the bytecode call result, the <strong>cast</strong> method can only specify the type corresponding to the bytecode.</p></div><p>For example we want to get a field of type <code>Boolean</code> and cast it to <code>String</code>.</p><p>The following is the wrong way to use it.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">field {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().string() </span><span style="color:#768390;">// ❗ Wrong usage, must be cast to the bytecode target type</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>The following is the correct way to use it.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">field {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;">}.get().boolean().toString() </span><span style="color:#768390;">// ✅ The correct way to use, get the type and then convert</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><h2 id="common-type-extensions" tabindex="-1"><a class="header-anchor" href="#common-type-extensions" aria-hidden="true">#</a> Common Type Extensions</h2><p>When find methods and fields, we usually need to specify the type in find conditions.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">field {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#6CB6FF;">Boolean</span><span style="color:#ADBAC7;">::</span><span style="color:#6CB6FF;">class</span><span style="color:#ADBAC7;">.javaPrimitiveType</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></div><p>Expressing the type of <code>Boolean::class.javaPrimitiveType</code> in <code>Kotlin</code> is very long and inconvenient.</p><p>Therefore, <code>YukiReflection</code> encapsulates common type calls for developers, including Android related types and Java common types and <strong>primitive type keywords</strong>.</p><p>At this time, the above type can be written in the following form.</p><blockquote><p>The following example</p></blockquote><div class="language-kotlin ext-kt line-numbers-mode"><pre class="shiki" style="background-color:#22272e;"><code><span class="line"><span style="color:#ADBAC7;">field {</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;">"test"</span></span>
|
||
<span class="line"><span style="color:#ADBAC7;"> type </span><span style="color:#F47067;">=</span><span style="color:#ADBAC7;"> </span><span style="color:#F69D50;">BooleanType</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></div><p>The <strong>primitive type keywords</strong> in common Java types have been encapsulated as <strong>Type(Class Name) + Type</strong>, such as <code>IntType</code>, <code>FloatType</code> (their bytecode types are <code>int</code>, <code> float</code>).</p><p>Correspondingly, array types also have convenient usage methods, assuming we want to get an array of type <code>String[]</code>.</p><p>You need to write <code>java.lang.reflect.Array.newInstance(String::class.java, 0).javaClass</code> to get this type.</p><p>Does it feel very troublesome, at this time we can use the method <code>ArrayClass(StringClass)</code> to get this type.</p><p>At the same time, since <code>String</code> is a common type, you can also directly use <code>StringArrayClass</code> to get this type.</p><p>The methods found in some common requirements have their corresponding encapsulation types for use, in the format <strong>Type(Class Name) + Class</strong>.</p><p>The following are wrapper names for some special case types in Java represented in <code>YukiReflection</code>.</p><ul><li><p><code>void</code> → <code>UnitType</code></p></li><li><p><code>java.lang.Void</code> → <code>UnitClass</code></p></li><li><p><code>java.lang.Object</code> → <code>AnyClass</code></p></li><li><p><code>java.lang.Integer</code> → <code>IntClass</code></p></li><li><p><code>java.lang.Character</code> → <code>CharClass</code></p></li></ul><div class="custom-container warning"><p class="custom-container-title">Notice</p><p>Encapsulating types with <strong>Type(Class Name) + Type</strong> will and only be represented as Java <strong>primitive type keywords</strong>.</p><p>Since the concept of <strong>primitive types</strong> does not exist in Kotlin, they will all be defined as <strong>KClass</strong>.</p><p>There are 9 <strong>primitive type keywords</strong> in Java, of which 8 are <strong>primitive type</strong>, namely <strong>boolean</strong>, <strong>char</strong>, <strong>byte</strong>, <strong>short</strong> , <strong>int</strong>, <strong>float</strong>, <strong>long</strong>, <strong>double</strong>, of which the <strong>void</strong> type is a special case.</p><p>At the same time, they all have their own corresponding package types in Java, such as <strong>java.lang.Boolean</strong>, <strong>java.lang.Integer</strong>, these types are <u><strong>unequal</strong></u>, Please note the distinction.</p><p>Similarly, arrays also have corresponding wrapper types, which also need to be distinguished from Java <strong>primitive type keywords</strong>.</p><p>For example, the encapsulation type of <strong>byte[]</strong> is <strong>ByteArrayType</strong> or <strong>ArrayClass(ByteType)</strong>, and the encapsulation type of <strong>Byte[]</strong> is <strong>ByteArrayClass</strong> or <strong>ArrayClass(ByteClass )</strong>, these types are also <u><strong>unequal</strong></u>.</p></div><div class="custom-container tip"><p class="custom-container-title">Tips</p><p>For more types, see <a href="../api/public/com/highcapable/yukireflection/type/android/ComponentTypeFactory">ComponentTypeFactory</a>, <a href="../api/public/com/highcapable/yukireflection/type/android/GraphicsTypeFactory">GraphicsTypeFactory</a>, <a href="../api/public/com/highcapable/yukireflection/type/android/ViewTypeFactory">ViewTypeFactory</a>, <a href="../api/public/com/highcapable/yukireflection/type/java/VariableTypeFactory">VariableTypeFactory</a>.</p></div><p>At the same time, you are welcome to contribute more commonly used types.</p></div><!--[--><!--]--></div><footer class="page-meta"><div class="meta-item edit-link"><a class="external-link meta-item-label" href="https://github.com/fankes/YukiReflection/edit/master/docs-source/src/en/api/features.md" rel="noopener noreferrer" target="_blank" aria-label="Edit this page on GitHub"><!--[--><!--]--> Edit this page on GitHub <span><svg class="external-link-icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg><span class="external-link-icon-sr-only">open in new window</span></span><!--[--><!--]--></a></div><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><!----></div><div class="meta-item contributors"><span class="meta-item-label">Contributors: </span><span class="meta-item-info"><!--[--><!--[--><span class="contributor" title="email: qzmmcn@163.com">fankesyooni</span><!----><!--]--><!--]--></span></div></footer><!----><!--[--><!--]--></main><!--]--></div><!----><!--]--></div>
|
||
<script type="module" src="/YukiReflection/assets/app.3cb5b3a5.js" defer></script>
|
||
</body>
|
||
</html>
|