xlang 的反射应用
xlang2026-02-11 16:37:17xlang 语言提供完整的反射体系(语言级别, VM支持)
四大类:
- Class , 类
- Field, 字段
- Method, 方法
- Object, 万物基类
1.Class 类:
class Class : public Object{
public Object newInstance();
public Object newInstance(Method ctor);
public Object newInstance(Method ctor, Object [] args);
public bool hasAnnotation();
public Class getSuperClass();
public Method[] getMethods();
public Method[] getMethods(String name, int flags);
public Field[] getFields();
public static Class getClass();
public JsonObject getAnnotations();
public bool extendsOf(Object c);
};
| 方法 | 语义 |
|---|---|
| newInstance() | 无参构造创建对象 |
| newInstance(Method ctor) | 使用指定构造函数创建对象 |
| newInstance(Method ctor, Object[] args) | 带参数创建对象 |
| hasAnnotation() | 判断类是否有注解 |
| getSuperClass() | 返回父类 Class |
| getMethods() | 获取所有方法(顺序不保证) |
| getMethods(name, flags) | 根据名称+标志筛选方法 |
| getFields() | 获取所有字段 |
| getClass() | 静态获取 Class 对象 |
| getAnnotations() | 返回类注解 JsonObject |
| extendsOf(Object c) | 判断是否继承或实现指定类 |
2.Method 类
class Method : public Object{
public static int FLAG_STATIC;
public static int FLAG_FINAL;
public static int FLAG_CONSTRUCTOR;
public static int FLAG_GLOBAL;
public static int FLAG_OVERRIDE;
public static int FLAG_ABSTRACT;
public static int FLAG_ENUM;
public static int FLAG_EXCEPTIONLIST;
public static int FLAG_PUBLIC;
public static int FLAG_PROTECTED;
public static int FLAG_ANNOTATE;
public static int FLAG_ALL;
public long toNative();
public Object invoke(Object own);
public Object invoke(Object own, Object [] args);
public bool hasAnnotation();
public Object getType();
public Object getParameterType(int n);
public int getParameterFlags(int n);
public int getParameterFlag(int n);
public int getParameterCount();
public String getName();
public int getFlags();
public int getThrowExceptionCount();
public Object getThrowExceptionItem(int n);
};
| 成员 | 类型 | 说明 | 用途 / 注意事项 |
|---|---|---|---|
| FLAG_STATIC | static int |
标记方法为静态方法 | 用于筛选方法或调用前检查 |
| FLAG_FINAL | static int |
标记方法不可覆盖 | 框架可据此判断可继承性 |
| FLAG_CONSTRUCTOR | static int |
标记方法为构造函数 | 构造函数只能通过 Class.newInstance() 调用 |
| FLAG_GLOBAL | static int |
全局作用域方法 | 用于全局函数标记 |
| FLAG_OVERRIDE | static int |
方法覆盖父类方法 | 框架可判断覆盖链 |
| FLAG_ABSTRACT | static int |
抽象方法 | 不能直接调用 invoke() |
| FLAG_ENUM | static int |
枚举类型的方法 | 仅枚举类特定方法 |
| FLAG_EXCEPTIONLIST | static int |
方法声明了异常列表 | 可用于动态调用异常处理 |
| FLAG_PUBLIC | static int |
公共方法 | 访问控制检查 |
| FLAG_PROTECTED | static int |
受保护方法 | 访问控制检查 |
| FLAG_ANNOTATE | static int |
方法带注解 | 用于注解驱动框架 |
| FLAG_ALL | static int |
全部方法标记 | 过滤时使用 |
| 方法 | 返回类型 | 说明 | 用途 / 注意事项 |
|---|---|---|---|
toNative() |
long |
返回底层原生函数指针 | 可用于性能优化或底层调用 |
invoke(Object own) |
Object |
调用无参方法 | own 必须为实例或类,静态方法可传 Class |
invoke(Object own, Object[] args) |
Object |
调用带参数方法 | 参数类型/数量必须匹配 |
hasAnnotation() |
bool |
判断方法是否带注解 | 用于 AOP / 路由 / 框架元数据 |
getType() |
Object |
返回方法返回值类型的 Class 对象 | 用于类型检查、动态调用 |
getParameterType(int n) |
Object |
获取第 n 个参数类型 | 用于动态调用、参数检查 |
getParameterFlags(int n) |
int |
第 n 个参数的特性集合 | 例如可选、非空等 |
getParameterFlag(int n) |
int |
第 n 个参数单个标记 | 更细粒度控制 |
getParameterCount() |
int |
方法参数数量 | 动态调用前必须匹配 |
getName() |
String |
方法名字 | 调试、筛选、动态调用 |
getFlags() |
int |
方法标志位集合 | 用于判断静态/构造/抽象等 |
getThrowExceptionCount() |
int |
方法声明异常数量 | 异常处理 / 框架动态调用 |
getThrowExceptionItem(int n) |
Object |
第 n 个异常类型(Class) | 动态捕获 / 类型检查 |
3.Field 类:
class Field : public Object{
public static int FLAG_STATIC;
public static int FLAG_CONST;
public static int FLAG_NOTNILPTR;
public static int FLAG_ALL;
public long toNative();
public Object getValue(Object own);
public bool setValue(Object own, Object args);
public bool hasAnnotation();
public bool isStatic();
public bool isConst();
public Object getType();
public String getName();
};
| 成员 | 类型 | 说明 | 用途 / 注意事项 |
|---|---|---|---|
| FLAG_STATIC | static int |
标记字段为静态字段 | 用于筛选静态字段或访问时无需实例 |
| FLAG_CONST | static int |
标记字段为常量 | 常量不可通过 setValue 修改 |
| FLAG_NOTNILPTR | static int |
字段不能为空 | 设置值时需要非 null |
| FLAG_ALL | static int |
全部字段标志 | 用于筛选字段 |
| 方法 | 返回类型 | 说明 | 用途 / 注意事项 |
|---|---|---|---|
getValue(Object own) |
Object |
获取字段值 | own 必须是实例对象;静态字段可传类对象或实例 |
setValue(Object own, Object args) |
bool |
设置字段值 | 返回设置是否成功;静态字段可传类对象或实例 |
hasAnnotation() |
bool |
判断字段是否有注解 | 用于注解驱动框架、元编程 |
isStatic() |
bool |
判断字段是否静态 | 方便区分实例字段和静态字段 |
isConst() |
bool |
判断字段是否常量 | 常量字段不允许修改 |
getType() |
Object |
返回字段类型的 Class 对象 | 用于类型检查或动态操作 |
getName() |
String |
字段名 | 调试、筛选、动态访问 |
4.Object 类:
class Object {
public void wait();
public void wait(int ms);
public String toString();
public void notify();
public void notifyAll();
public bool isArrayObject();
public bool instanceOf(Class c);
public long hash();
public long getPtr();
public long getObjectPtr();
public Class getComponentType();
public Class getClass();
public static Object fromHash();
};
说明:
| 方法 | 语义 |
|---|---|
| wait() / wait(ms) | 阻塞当前线程,可指定超时 |
| notify() / notifyAll() | 唤醒等待对象锁的线程 |
| toString() | 返回对象字符串表示 |
| isArrayObject() | 判断是否数组对象 |
| instanceOf(Class c) | 判断对象类型是否为 c 或其子类 |
| hash() | 返回对象哈希值 |
| getPtr() / getObjectPtr() | 获取对象内存指针 |
| getComponentType() | 如果是数组对象,返回元素类型 |
| getClass() | 获取对象类型的 Class 元对象 |
| fromHash() | 静态方法,通过 hash 获取对象引用(实现可选) |
代码示例:
class TestClass{
String text;
static int a;
char c;
TestClass(){}
@Annotate(Name="user")
public int add(){
return 123;
}
static void Add(int n){return ;}
TestClass(String s){text =s ;}
};
void testReflex(){
/** 获取名为 TestClass 的类*/
Class clazz = Class.getClass("TestClass");
/** 从默认构造函数 构造一个实例, 注意, 如无默认构造函数, 则可能构造失败*/
Object st = clazz.newInstance();
/** 获取类的所有方法, 含静态*/
Method [] mm = clazz.getMethods();
/** 打印方法名*/
System.out.print(mm[1].getName());
/** 调用第一个方法, 参数为实例对象*/
int i = (int)mm[1].invoke(st);
/** 获取对象的注解*/
JsonObject json = mm[1].getAnnotations();
if (json != nilptr){
/** 遍历注解*/
JsonNode sub = json.child();
while (sub != nilptr){
System.out.print(sub.getName());
if (sub.getType() == JsonNode.JSONTYPE_OBJECT){
JsonObject jobj = (JsonObject)sub;
System.out.print(jobj.getString("Name"));
break;
}
sub = sub.next();
}
}
/*** 从第一个造函数构造类实例*/
st = clazz.newInstance((clazz.getMethods("TestClass", Method.FLAG_CONSTRUCTOR))[0]);
/*** 给第0个字段赋值为字符串 hello */
clazz.getFields()[0].setValue(st, "hello");
/** 获取第0个字段的值**/
String fv = (String)clazz.getFields()[0].getValue(st);
/***打印值 */
System.out.print("get is " + fv + "\n");
/** 打印第二个方法的名称*/
System.out.print(mm[2].getName());
/** 从带参数的构造函数构造类实例*/
st = clazz.newInstance(mm[2], "value seted");
/*** 调用第二个方法, 静态方法*/
mm[3].invoke(clazz, 2);
}
xnl / cxnl 接口中反射相关定义
#define REFLEX_FLAG_CONST 0x2
#define REFLEX_FLAG_STATIC 0x4
#define REFLEX_FLAG_NONNIL 0x8
#define REFLEX_FLAG_OVRRID 0x10
#define REFLEX_FLAG_ABSTRT 0x20
#define REFLEX_FLAG_ENUM 0x40
#define REFLEX_FLAG_CTOR 0x40
#define REFLEX_FLAG_EXCEPT 0x80
#define INVOKE_ONLY 0
#define INVOKE_CHECKARGS 1
#define INVOKE_PUSHARGS 2
#define INVOKE_SECURE 3
// 将异常设置为默认行为
#define EXCEPTION_DEFAULT 0
// 保留异常, 调用结束后恢复现场, 保留异常状态并由native进行处理
#define EXCEPTION_RESEVER 0x8
// 向上传递, 调用结束后不恢复现场, 向上传递至外层xlang代码中的 try catch 进行回复
#define EXCEPTION_UPWRAD 0x10
// 就地直接报告异常
#define EXCEPTION_REPORT 0x20
#define EXCEPTION_SKIP_MASK (EXCEPTION_RESEVER | EXCEPTION_UPWRAD)
#define EXCEPTION_MASK (EXCEPTION_RESEVER | EXCEPTION_UPWRAD | EXCEPTION_REPORT)
virtual XObject* getClass(const char* classname) = 0;
virtual XObject* getMethod(XContext* context, XObject* pclass, const char* methodname) = 0;
virtual XObject* getFields(XContext* context, XObject* object, const char* fieldname) = 0;
virtual int getMethodFlags(XObject*) = 0;
virtual int getFieldFlags(XObject* a) = 0;
virtual const char* getMethodName(XObject*, size_t* size) = 0;
virtual const char* getFieldName(XObject* o, size_t* size) = 0;
virtual const char* getClassName(XObject*, size_t* size) = 0;
virtual XObject* getReturnType(XContext* context, XObject*) = 0;
virtual int getParameterCount(XObject*) = 0;
virtual XObject* getParameterType(XContext* context, XObject*, int n) = 0;
virtual bool ref_checkParameterType(XContext* context, XObject* method, XObject* paramsPack) = 0;
virtual bool ref_pushParameter(XContext* context, XObject* method, XObject* paramsPack) = 0;
virtual bool ref_invoke(XContext* context, XObject* pthis, XObject* method, XObject* paramsPack, XObject* out, int callFlags) = 0;
virtual bool isClass(XObject* object) = 0;
virtual bool isInstanceOf(XObject* object, XObject* _class, bool allowExtends) = 0;
virtual XDataType getObjectType(XObject* object) = 0;
virtual XObject* getObjectClass(XObject* object) = 0;
virtual void* getClassObject(XObject* object) = 0;
virtual XObject* getBaseClass(XObject* _classobject) = 0;
virtual xlong getHash(XObject * object) = 0;
virtual XObject* fromHash(xlong) = 0;
virtual const char * toString(XContext* context, XObject* object) = 0;
virtual XObject* getFieldType(XContext* context, XObject*) = 0;
virtual XObject* getFieldValue(XObject*, XObject*) = 0;
virtual bool setFieldValue(XContext* context, XObject*, XObject* field, XObject* value) = 0;
virtual int getFieldId(const char* path) = 0;
virtual XObject* getDynamicField(XObject* object, int id) = 0;
virtual XObject* getStaticField(XObject* object, int id) = 0;
virtual bool isExtendsOf(XObject* eclass, XObject* bclass) = 0;
标志位定义(Method / Field 特性)
| 宏 | 值 | 说明 |
|---|---|---|
| REFLEX_FLAG_CONST | 0x2 | 字段或方法是常量 |
| REFLEX_FLAG_STATIC | 0x4 | 静态字段或方法 |
| REFLEX_FLAG_NONNIL | 0x8 | 字段/参数不能为 nilptr |
| REFLEX_FLAG_OVRRID | 0x10 | 方法覆盖父类方法 |
| REFLEX_FLAG_ABSTRT | 0x20 | 方法抽象 |
| REFLEX_FLAG_ENUM | 0x40 | 枚举方法 |
| REFLEX_FLAG_CTOR | 0x40 | 构造函数方法(与枚举共用标志) |
| REFLEX_FLAG_EXCEPT | 0x80 | 方法声明了异常列表 |
调用模式(ref_invoke callFlags)
| 宏 | 值 | 说明 |
|---|---|---|
| INVOKE_ONLY | 0 | 无参数检查,直接调用 |
| INVOKE_CHECKARGS | 1 | 检查参数类型和数量 |
| INVOKE_PUSHARGS | 2 | 将参数压入调用栈 |
| INVOKE_SECURE | 3 | 安全模式调用,检查异常和权限 |
异常处理标志
| 宏 | 值 | 说明 |
|---|---|---|
| EXCEPTION_DEFAULT | 0 | 默认异常行为 |
| EXCEPTION_RESEVER | 0x8 | 保留异常状态,由 native 层处理,调用结束恢复现场 |
| EXCEPTION_UPWRAD | 0x10 | 向上传递异常,不恢复现场,交给 xlang try/catch |
| EXCEPTION_REPORT | 0x20 | 就地直接报告异常 |
| EXCEPTION_SKIP_MASK | EXCEPTION_RESEVER | EXCEPTION_UPWRAD | 异常跳过掩码 |
| EXCEPTION_MASK | EXCEPTION_RESEVER | EXCEPTION_UPWRAD | EXCEPTION_REPORT | 异常掩码组合 |
类型与类操作
| 函数 | 返回类型 | 参数 | 说明 |
|---|---|---|---|
| getClass | XObject* | const char* classname | 获取指定类对象 |
| isClass | bool | XObject* object | 判断对象是否是 Class |
| getObjectClass | XObject* | XObject* object | 获取对象所属类 |
| getClassObject | void* | XObject* object | 获取底层类对象指针(native) |
| getBaseClass | XObject* | XObject* _classobject | 获取父类 |
| isExtendsOf | bool | XObject* eclass, XObject* bclass | 判断继承关系 |
| isInstanceOf | bool | XObject* object, XObject* _class, bool allowExtends | 判断对象是否为指定类(可考虑继承) |
| getObjectType | XDataType | XObject* object | 获取对象类型枚举 |
| getHash | xlong | XObject* object | 获取对象哈希值 |
| fromHash | XObject* | xlong | 根据哈希获取对象 |
方法操作(Method 元对象相关)
| 函数 | 返回类型 | 参数 | 说明 |
|---|---|---|---|
| getMethod | XObject* | XContext* context, XObject* pclass, const char* methodname | 获取指定方法对象 |
| getMethodFlags | int | XObject* | 获取方法标志位(静态 / 构造 / 抽象 / 注解等) |
| getMethodName | const char* | XObject*, size_t* size | 获取方法名字 |
| getReturnType | XObject* | XContext* context, XObject* | 获取返回值类型 Class |
| getParameterCount | int | XObject* | 方法参数数量 |
| getParameterType | XObject* | XContext*, XObject*, int n | 第 n 个参数类型 |
| ref_checkParameterType | bool | XContext*, XObject* method, XObject* paramsPack | 检查参数类型匹配 |
| ref_pushParameter | bool | XContext*, XObject* method, XObject* paramsPack | 将参数压栈 |
| ref_invoke | bool | XContext*, XObject* pthis, XObject* method, XObject* paramsPack, XObject* out, int callFlags |
字段操作(Field 元对象相关)
| 函数 | 返回类型 | 参数 | 说明 |
|---|---|---|---|
| getFields | XObject* | XContext*, XObject* object, const char* fieldname | 获取指定字段对象 |
| getFieldFlags | int | XObject* a | 获取字段标志位(静态/常量/非空等) |
| getFieldName | const char* | XObject* o, size_t* size | 字段名 |
| getFieldType | XObject* | XContext*, XObject* | 字段类型 Class |
| getFieldValue | XObject* | XObject* object, XObject* field | 获取字段值 |
| setFieldValue | bool | XContext*, XObject*, XObject* field, XObject* value | 设置字段值 |
| getFieldId | int | const char* path | 根据字段路径获取字段 id |
| getDynamicField | XObject* | XObject* object, int id | 获取对象动态字段 |
| getStaticField | XObject* | XObject* object, int id | 获取对象静态字段 |
类、方法、字段名字与字符串
| 函数 | 返回类型 | 参数 | 说明 |
|---|---|---|---|
| getMethodName | const char* | XObject*, size_t* size | 获取方法名 |
| getFieldName | const char* | XObject*, size_t* size | 获取字段名 |
| getClassName | const char* | XObject*, size_t* size | 获取类名 |
| toString | const char* | XContext*, XObject* object | 获取对象字符串表示 |
用途说明:
xnl / cxnl 是为底层程序与xlang vm沟通的接口, 通过此接口, 可以使底层模块更好的与xlang vm交互, 以下以 quickjs 引擎为例:
在 quickjs 引擎模块中, 为了在 js 中调用上层的xlang代码, 实现js <-> 无障碍调用, 使用xnl中的反射功能, 将vm 中需要用到的类通过反射全部解析出来, 然后构造 js 中的桥接对象, 以达到设计目的.
例如 MyClass 类在 js 中被使用时:
- js 引擎通过 gs_env->getClassName("MyClass") 查询虚拟机中的类对象 object, 并构造对应的内部对象.
- 通过 gs_env->getMethod(ctx.getThread(), object, 0) 遍历类对象的方法, 在 quickjs 中使用 JSCFunctionListEntry 构造对应的函数列表.
- 通过 gs_env->getFields(ctx.getThread(), object, 0) 遍历对象的字段及其信息, 通过 JS_DefinePropertyValueStr 关联相应的操作方法.
- 将内部对象与前两步构造的函数列表和字段操作进行关联, 并注册到 quickjs 的系统中.
完成以上4步以后, 就可以在 js 代码中使用 Myclass 类, 该套方法具有完全自动化, 无需特化处理的处理特点, 可将 xlang vm中的任意对象构造对应的 js 对象并实现上下层的无障碍调用.
反射限制说明
核心规则
-
四大类不被反射 (可以查询到对象,但无法进一步查询到他们的成员和方法)
-
Class -
Method -
Field -
Object
-
-
含义
-
无法通过反射 API(
Class.getClass(),getMethods(),getFields()等)获取它们自身的类信息、方法或字段 -
即使在 xnl/cxnl 中,也无法像普通类那样遍历或操作这四大类.
-
-
原因
-
这四大类是 反射体系的基础元对象
-
允许反射查询其他类,如果允许反射自身,会引入无限递归或自引用问题
-
保护底层元对象结构,保证反射机制的稳定性
-
-
注意事项
-
对普通类(用户定义类、系统类)可以完全反射
-
对四大类本身,只能通过 底层接口或原生指针 进行操作
-
调用
getClass("Class")或getMethods()不能获取 Class 的方法列表
-
- 结构固定性
- 不能动态修改成员方法或者字段
- 不能在运行期间动态生成类对象以及方法/字段
总结:
四大类是 反射体系的底层基础,它们自身无法被反射,但它们定义的接口和方法支撑了对其它类的完整反射操作。这是 xlang VM 设计上的安全和稳定策略。
上一篇:使用X-Stuidio进行ESP32项目开发下一篇:XStudio 在linux上的使用

