Skip to content

fix: how to call static method of class - #2

Open
webbrain-one wants to merge 1 commit into
zeshaoaaa:masterfrom
webbrain-one:webbrain/issue-1
Open

fix: how to call static method of class#2
webbrain-one wants to merge 1 commit into
zeshaoaaa:masterfrom
webbrain-one:webbrain/issue-1

Conversation

@webbrain-one

@webbrain-one webbrain-one commented Aug 9, 2026

Copy link
Copy Markdown

Closes #1

Patch generated by qwen3.6-35b-a3b via local API.


Summary by cubic

Allow calling static methods in OkReflect without creating an instance by adding static() and routing calls with a null target. Fixes exceptions in call().get() for static methods; closes #1.

  • Bug Fixes
    • Added static() to operate on static methods/fields without create().
    • Updated invocation to pass a null target when marked static to prevent errors.

Written for commit b1e5796. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added support for configuring reflection operations to target static members.
    • Static method calls now work without an instance, while instance-based calls continue to operate as before.

Previously, calling static methods via `call().get()` threw an exception unless `create()` was used, forcing class instantiation. Updated `OkReflect` to bypass `create()` for static invocations, enabling direct static method execution without object creation. Closes zeshaoaaa#1.

Patch generated by qwen3.6-35b-a3b via local API.
@devactivity-app

Copy link
Copy Markdown

@webbrain-one, ⭐3 XP earned, 🏆First Pull Request Pushed completed, 💪Level 1 achieved!
Contribute more to raise your XP/Level, complete challenges for extra achievements! [Sign up for personal dashboard]

icon

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OkReflect adds a static() configuration method. Static mode clears the configured instance and invokes methods with a null reflection target. Instance mode retains the existing configured-instance target.

Changes

Static member support

Layer / File(s) Summary
Static configuration and invocation
src/main/kotlin/okreflect/OkReflect.kt
Adds static() to enable static-member mode and clear the instance. Method invocation uses a null target in static mode and the configured instance otherwise.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the fix for invoking static methods on reflected classes.
Linked Issues check ✅ Passed The changes enable direct static method invocation without creating an instance, which satisfies issue #1.
Out of Scope Changes check ✅ Passed The changes are limited to static reflection configuration and invocation behavior required by issue #1.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/kotlin/okreflect/OkReflect.kt`:
- Around line 238-247: Update the static-mode flow around `OkReflect.static()`
and `realGet()` so the target class is always initialized via `initClazz()`
before static method or field lookup, while still skipping instance
construction. Preserve the existing behavior for both
`OkReflect.on(Class).static()` and `OkReflect.on(String).static()`, and add
regression coverage for each entry path.
- Around line 242-245: Add a Java-safe alias such as staticMembers() alongside
OkReflect.`static`() that selects the same static mode by reusing the existing
implementation, and extend the Java-facing tests to invoke and verify the alias.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2601081b-2247-4375-aec5-1072b0cd35bd

📥 Commits

Reviewing files that changed from the base of the PR and between 2a5611a and b1e5796.

📒 Files selected for processing (1)
  • src/main/kotlin/okreflect/OkReflect.kt

Comment on lines +238 to +247
/**
* Marks the current OkReflect instance to operate on static members.
* No instance will be created, allowing calls to static methods/fields.
*/
fun `static`(): OkReflect {
withOuterInstance = true
instance = null
return this
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Expect: static mode initializes clazz before getMethod() is called.
rg -n -C 8 \
  'fun `static`\(|private fun realGet|private fun initClazz|\bgetMethod\s*\(' \
  src/main/kotlin src/test

Repository: zeshaoaaa/OkReflect

Length of output: 7485


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== OkReflect.kt core sections =="
sed -n '1,140p' src/main/kotlin/okreflect/OkReflect.kt
echo
sed -n '220,280p' src/main/kotlin/okreflect/OkReflect.kt
echo
sed -n '300,385p' src/main/kotlin/okreflect/OkReflect.kt
echo
sed -n '520,590p' src/main/kotlin/okreflect/OkReflect.kt

echo
echo "== Static usage / tests =="
rg -n -C 4 'static\(\)|\.on\("(?:[^"]*|[^"]*)")|static method|getMethod\(' src/test src/main/kotlin || true

Repository: zeshaoaaa/OkReflect

Length of output: 10702


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== OkReflect static API declarations =="
rg -n -C 5 'on\s*\(|fun on\s*\(|companion|object' src/main/kotlin/okreflect/OkReflect.kt

echo
echo "== MethodGetter implementation =="
sed -n '1,170p' src/main/kotlin/okreflect/MethodGetter.kt

echo
echo "== Static usage/tests =="
rg -n -C 4 'static\(\)|`static`\(' src/test src/main/kotlin || true
rg -n -C 3 'on\(".*"\)' src/test src/main/kotlin || true

echo
echo "== Read-only Kotlin flow probe =="
python3 - <<'PY'
from pathlib import Path

p = Path("src/main/kotlin/okreflect/OkReflect.kt")
s = p.read_text()
checks = {
    "String constructor sets className": "constructor(className: String)\n        this.className = className" in s,
    "static sets withOuterInstance true": "fun `static`():" in s and "withOuterInstance = true" in s.split("fun `static`()")[1].split("fun with")[0],
    "realGet skips initClazz when withOuterInstance": "if (!withOuterInstance) {" in s and "initClazz()" in s.split("if (!withOuterInstance) {",1)[0],
    "invoke passes current clazz to getMethod": 'getMethod(clazz, methodCall.classes' in s,
    "initClazz initializes clazz from className": "private fun initClazz()\n        if (clazz == null) {\n            this.clazz = Class.forName(className!!)" in s,
}
for k, v in checks.items():
    print(f"{k}: {v}")
PY

Repository: zeshaoaaa/OkReflect

Length of output: 26518


Load clazz before invoking static methods.

OkReflect.on(String) sets only className, so clazz is null. In static mode, realGet() skips initClazz() and passes null to getMethod(), which fails before the reflection call. Keep class loading enabled for the static path, or use a separate static-mode flag that bypasses construction but not class initialization. Add regression tests for both OkReflect.on(Class).static()) and OkReflect.on(String).static().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/okreflect/OkReflect.kt` around lines 238 - 247, Update the
static-mode flow around `OkReflect.static()` and `realGet()` so the target class
is always initialized via `initClazz()` before static method or field lookup,
while still skipping instance construction. Preserve the existing behavior for
both `OkReflect.on(Class).static()` and `OkReflect.on(String).static()`, and add
regression coverage for each entry path.

Comment on lines +242 to +245
fun `static`(): OkReflect {
withOuterInstance = true
instance = null
return this

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Expect: a Java-safe alias or JVM-name mapping for static mode.
rg -n -C 5 \
  'fun `static`\(|`@JvmName`|staticMembers|\.static\(\)' \
  src/main/kotlin src/test

Repository: zeshaoaaa/OkReflect

Length of output: 921


🏁 Script executed:

#!/usr/bin/env/bash
set -euo pipefail

echo "== OkReflect.kt relevant declarations =="
wc -l src/main/kotlin/okreflect/OkReflect.kt
sed -n '1,90p' src/main/kotlin/okreflect/OkReflect.kt
sed -n '220,255p' src/main/kotlin/okreflect/OkReflect.kt

echo "== build config =="
fd -a 'gradle|build\.kts|settings\.gradle|pom\.xml|build\.gradle' . | sed 's#^\./##'

echo "== Java static tests/usages =="
rg -n -C 3 'OkReflect|\.static\(|withOuterInstance|staticMembers|`@JvmName`' src/test src/main/kotlin/okreflect || true

echo "== Java reserved keyword and Kotlin backticked identifier probe =="
python3 - <<'PY'
import pathlib, re
files = list(map(pathlib.Path, pathlib.Path('.').rglob('*')))
text = '\n'.join(str(p) for p in files)
print("sample of OkReflect.kt:", pathlib.Path('src/main/kotlin/okreflect/OkReflect.kt').read_text()[:1200])
PY

# Read-only: demonstrate Java source cannot treat static as an identifier token in a valid type-qualified method call expression.
printf 'valid Java identifiers from reserved words: null, true, false\n'
tmp="$(mktemp -d)"
printf 'package p; class X { void f() { p.OkReflect.static().toString(); } }\n' > "$tmp/X.java"
javac -d "$tmp" "$tmp/X.java" 2>&1 || true
javac -version 2>&1 | sed -n '1p'
rm -rf "$tmp"

Repository: zeshaoaaa/OkReflect

Length of output: 50377


🏁 Script executed:

#!/usr/bin/env/bash
set -euo pipefail

echo "== OkReflect.kt relevant declarations =="
wc -l src/main/kotlin/okreflect/OkReflect.kt
sed -n '1,90p' src/main/kotlin/okreflect/OkReflect.kt
sed -n '220,255p' src/main/kotlin/okreflect/OkReflect.kt

echo "== build config =="
fd -a 'gradle|build\.kts|settings\.gradle|pom\.xml|build\.gradle' . | sed 's#^\./##'

echo "== Java static tests/usages =="
rg -n -C 3 'OkReflect|\.static\(|withOuterInstance|staticMembers|`@JvmName`' src/test src/main/kotlin/okreflect || true

echo "== Java reserved keyword and Kotlin backticked identifier probe =="
python3 - <<'PY'
import pathlib, re
files = list(map(pathlib.Path, pathlib.Path('.').rglob('*')))
print("sample of OkReflect.kt:", pathlib.Path('src/main/kotlin/okreflect/OkReflect.kt').read_text()[:1200])
PY

# Read-only: show Java source cannot treat static as an identifier token in a type-qualified method-call form.
printf 'valid Java identifiers from reserved words: null, true, false\n'
tmp="$(mktemp -d)"
printf 'package p; class X { void f() { p.OkReflect.static().toString(); } }\n' > "$tmp/X.java"
javac -d "$tmp" "$tmp/X.java" 2>&1 || true
javac -version 2>&1 | sed -n '1p'
rm -rf "$tmp"

Repository: zeshaoaaa/OkReflect

Length of output: 50377


🌐 Web query:

Java compiler reserved word cannot be used as an identifier example static

💡 Result:

In Java, a reserved keyword cannot be used as an identifier [1][2]. Because 'static' is a reserved keyword in the Java programming language, attempting to use it as an identifier (for example, naming a variable, method, or class 'static') will result in a compile-time error [1][3][4]. The Java Language Specification (JLS) mandates that an identifier never have the same spelling as a reserved keyword, a boolean literal, or the null literal [1][2]. During tokenization, the compiler adheres to the "longest possible translation" rule; if a sequence of characters matches a reserved keyword, it is reduced to a keyword token rather than an identifier [1][5][2]. For example, if you attempt to write: int static = 10; // Compile-time error The compiler will reject this because 'static' is a reserved keyword and cannot function as a user-defined name [1][6]. While Java also includes "contextual keywords" (such as 'var' or 'yield') that can sometimes act as identifiers depending on where they appear, 'static' is a fully reserved keyword and is restricted in all contexts [1][7][2].

Citations:


Expose a Java-callable name for static mode.

The JVM method generated for fun static() is named static, and Java source cannot call a member whose identifier spelling is the reserved static keyword. Add a Java-safe alias such as staticMembers() and cover it in the Java tests.

Possible compatibility fix
+    fun staticMembers(): OkReflect = `static`()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun `static`(): OkReflect {
withOuterInstance = true
instance = null
return this
fun `static`(): OkReflect {
withOuterInstance = true
instance = null
return this
}
fun staticMembers(): OkReflect = `static`()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/okreflect/OkReflect.kt` around lines 242 - 245, Add a
Java-safe alias such as staticMembers() alongside OkReflect.`static`() that
selects the same static mode by reusing the existing implementation, and extend
the Java-facing tests to invoke and verify the alias.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/main/kotlin/okreflect/OkReflect.kt">

<violation number="1" location="src/main/kotlin/okreflect/OkReflect.kt:242">
P2: The new method is named `static` using Kotlin's backtick-escaped identifier syntax, but `static` is a reserved keyword in Java. Java callers will not be able to invoke this method using normal syntax (`okReflect.static()`), which breaks Java interop for consumers of this library. Consider adding a Java-callable alias such as `staticMembers()` that delegates to `static()`, and cover it with a Java-based test.</violation>

<violation number="2" location="src/main/kotlin/okreflect/OkReflect.kt:242">
P3: The new `static()` block was inserted between the KDoc for `with(...)` and the `with()` method body. As a result `with()` has lost its documentation (`@param instance ... pass the instance in this method` comment now sits detached above `static()`), and `static()` ended up with two consecutive Javadoc blocks — the first one actually describing `with()`. This misassociates the API docs. Recommend placing the entire new `static()` method and its own doc comment *before* the existing `with()` doc comment so each method keeps its matching documentation.</violation>

<violation number="3" location="src/main/kotlin/okreflect/OkReflect.kt:243">
P1: Static calls created with `on("fully.qualified.Class")` fail before invocation because static mode skips class initialization. Initialize `clazz` in `static()` before enabling outer-instance mode so both class-name and `Class` entry points work.</violation>

<violation number="4" location="src/main/kotlin/okreflect/OkReflect.kt:342">
P3: The new `targetObj` conditional is a no-op: in every case it evaluates to exactly `instance` (or `null` when `instance` is null). Concretely, when `instance == null` but `withOuterInstance` is false, the conditional falls through to `instance` (i.e. null); when `instance != null` it also returns `instance`. So `method.invoke(targetObj, *args)` behaves identically to the pre-change `method.invoke(instance, *args)`. The actual mechanism that makes static calls work in this PR is `static()` toggling `withOuterInstance = true`, which reroutes `realGet` into the `else` branch that skips constructor verification — the `targetObj` expression adds no behavior. Consider dropping the local and passing `instance` directly to avoid misleading logic that suggests it changes static vs. instance dispatch when it does not.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

* No instance will be created, allowing calls to static methods/fields.
*/
fun `static`(): OkReflect {
withOuterInstance = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Static calls created with on("fully.qualified.Class") fail before invocation because static mode skips class initialization. Initialize clazz in static() before enabling outer-instance mode so both class-name and Class entry points work.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main/kotlin/okreflect/OkReflect.kt, line 243:

<comment>Static calls created with `on("fully.qualified.Class")` fail before invocation because static mode skips class initialization. Initialize `clazz` in `static()` before enabling outer-instance mode so both class-name and `Class` entry points work.</comment>

<file context>
@@ -235,6 +235,16 @@ open class OkReflect {
+     * No instance will be created, allowing calls to static methods/fields.
+     */
+    fun `static`(): OkReflect {
+        withOuterInstance = true
+        instance = null
+        return this
</file context>
Suggested change
withOuterInstance = true
if (clazz == null) initClazz()
withOuterInstance = true

* Marks the current OkReflect instance to operate on static members.
* No instance will be created, allowing calls to static methods/fields.
*/
fun `static`(): OkReflect {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new method is named static using Kotlin's backtick-escaped identifier syntax, but static is a reserved keyword in Java. Java callers will not be able to invoke this method using normal syntax (okReflect.static()), which breaks Java interop for consumers of this library. Consider adding a Java-callable alias such as staticMembers() that delegates to static(), and cover it with a Java-based test.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main/kotlin/okreflect/OkReflect.kt, line 242:

<comment>The new method is named `static` using Kotlin's backtick-escaped identifier syntax, but `static` is a reserved keyword in Java. Java callers will not be able to invoke this method using normal syntax (`okReflect.static()`), which breaks Java interop for consumers of this library. Consider adding a Java-callable alias such as `staticMembers()` that delegates to `static()`, and cover it with a Java-based test.</comment>

<file context>
@@ -235,6 +235,16 @@ open class OkReflect {
+     * Marks the current OkReflect instance to operate on static members.
+     * No instance will be created, allowing calls to static methods/fields.
+     */
+    fun `static`(): OkReflect {
+        withOuterInstance = true
+        instance = null
</file context>

val args = methodCall.args
val method = getMethod(clazz, methodCall.classes, methodCall.methodName, args)
val returnType = method!!.returnType.toString()
val targetObj = if (withOuterInstance && instance == null) null else instance

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new targetObj conditional is a no-op: in every case it evaluates to exactly instance (or null when instance is null). Concretely, when instance == null but withOuterInstance is false, the conditional falls through to instance (i.e. null); when instance != null it also returns instance. So method.invoke(targetObj, *args) behaves identically to the pre-change method.invoke(instance, *args). The actual mechanism that makes static calls work in this PR is static() toggling withOuterInstance = true, which reroutes realGet into the else branch that skips constructor verification — the targetObj expression adds no behavior. Consider dropping the local and passing instance directly to avoid misleading logic that suggests it changes static vs. instance dispatch when it does not.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main/kotlin/okreflect/OkReflect.kt, line 342:

<comment>The new `targetObj` conditional is a no-op: in every case it evaluates to exactly `instance` (or `null` when `instance` is null). Concretely, when `instance == null` but `withOuterInstance` is false, the conditional falls through to `instance` (i.e. null); when `instance != null` it also returns `instance`. So `method.invoke(targetObj, *args)` behaves identically to the pre-change `method.invoke(instance, *args)`. The actual mechanism that makes static calls work in this PR is `static()` toggling `withOuterInstance = true`, which reroutes `realGet` into the `else` branch that skips constructor verification — the `targetObj` expression adds no behavior. Consider dropping the local and passing `instance` directly to avoid misleading logic that suggests it changes static vs. instance dispatch when it does not.</comment>

<file context>
@@ -329,11 +339,12 @@ open class OkReflect {
         val args = methodCall.args
         val method = getMethod(clazz, methodCall.classes, methodCall.methodName, args)
         val returnType = method!!.returnType.toString()
+        val targetObj = if (withOuterInstance && instance == null) null else instance
         if (returnType == "void") {
-            method.invoke(instance, *args)
</file context>

* Marks the current OkReflect instance to operate on static members.
* No instance will be created, allowing calls to static methods/fields.
*/
fun `static`(): OkReflect {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new static() block was inserted between the KDoc for with(...) and the with() method body. As a result with() has lost its documentation (@param instance ... pass the instance in this method comment now sits detached above static()), and static() ended up with two consecutive Javadoc blocks — the first one actually describing with(). This misassociates the API docs. Recommend placing the entire new static() method and its own doc comment before the existing with() doc comment so each method keeps its matching documentation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main/kotlin/okreflect/OkReflect.kt, line 242:

<comment>The new `static()` block was inserted between the KDoc for `with(...)` and the `with()` method body. As a result `with()` has lost its documentation (`@param instance ... pass the instance in this method` comment now sits detached above `static()`), and `static()` ended up with two consecutive Javadoc blocks — the first one actually describing `with()`. This misassociates the API docs. Recommend placing the entire new `static()` method and its own doc comment *before* the existing `with()` doc comment so each method keeps its matching documentation.</comment>

<file context>
@@ -235,6 +235,16 @@ open class OkReflect {
+     * Marks the current OkReflect instance to operate on static members.
+     * No instance will be created, allowing calls to static methods/fields.
+     */
+    fun `static`(): OkReflect {
+        withOuterInstance = true
+        instance = null
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

how to call static method of class

1 participant