文字大小:

xlang 的反射应用

xlang2026-02-11 16:37:17




xlang 语言提供完整的反射体系(语言级别, 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 中被使用时:

  1. js 引擎通过 gs_env->getClassName("MyClass") 查询虚拟机中的类对象 object, 并构造对应的内部对象.
  2. 通过 gs_env->getMethod(ctx.getThread(), object, 0) 遍历类对象的方法, 在 quickjs 中使用 JSCFunctionListEntry 构造对应的函数列表.
  3. 通过 gs_env->getFields(ctx.getThread(), object, 0) 遍历对象的字段及其信息, 通过 JS_DefinePropertyValueStr 关联相应的操作方法.
  4. 将内部对象与前两步构造的函数列表和字段操作进行关联, 并注册到 quickjs 的系统中.

完成以上4步以后, 就可以在 js 代码中使用 Myclass 类, 该套方法具有完全自动化, 无需特化处理的处理特点, 可将 xlang vm中的任意对象构造对应的 js 对象并实现上下层的无障碍调用.

反射限制说明

核心规则

  1. 四大类不被反射 (可以查询到对象,但无法进一步查询到他们的成员和方法)

    • Class

    • Method

    • Field

    • Object

  2. 含义

    • 无法通过反射 API(Class.getClass(), getMethods(), getFields() 等)获取它们自身的类信息、方法或字段

    • 即使在 xnl/cxnl 中,也无法像普通类那样遍历或操作这四大类.

  3. 原因

    • 这四大类是 反射体系的基础元对象

    • 允许反射查询其他类,如果允许反射自身,会引入无限递归或自引用问题

    • 保护底层元对象结构,保证反射机制的稳定性

  4. 注意事项

    • 对普通类(用户定义类、系统类)可以完全反射

    • 对四大类本身,只能通过 底层接口或原生指针 进行操作

    • 调用 getClass("Class")getMethods() 不能获取 Class 的方法列表

  5. 结构固定性
    • 不能动态修改成员方法或者字段
    • 不能在运行期间动态生成类对象以及方法/字段

总结
四大类是 反射体系的底层基础,它们自身无法被反射,但它们定义的接口和方法支撑了对其它类的完整反射操作。这是 xlang VM 设计上的安全和稳定策略。






上一篇:使用X-Stuidio进行ESP32项目开发下一篇:XStudio 在linux上的使用

评论

写评论

点击刷新