type information - The Class Object

本文深入探讨了Java类加载过程,解析了类加载器如何按需加载类对象,并执行静态初始化。通过具体示例,展示了Class.forName方法的使用,包括其参数、返回值及可能抛出的异常。

The class loader first checks to see if the Class Object for that type is loaded. If not, the default class loader finds the .class file with that name (an add-on class loader might, for example, look for the bytecodes in a database instead).

  • Each class object is loaded only when it's needed.
  • The static initialization is performed upon class loading.

forName

public static Class<?> forName(String className)
                        throws ClassNotFoundException

Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:

Class.forName(className, true, currentLoader)

where currentLoader denotes the defining class loader of the current class.

For example, the following code fragment returns the runtime Class descriptor for the class named java.lang.Thread:

Class t = Class.forName("java.lang.Thread")

A call to forName("X") causes the class named X to be initialized.

Parameters:

className - the fully qualified name of the desired class.

Returns:

the Class object for the class with the specified name.

Throws:

LinkageError - if the linkage fails

ExceptionInInitializerError - if the initialization provoked by this method fails

ClassNotFoundException - if the class cannot be located

 

For example

// typeinfo/SweetShop.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Examination of the way the class loader works

class Cookie {
  static {
    System.out.println("Loading Cookie");
  }
}

class Gum {
  static {
    System.out.println("Loading Gum");
  }
}

class Candy {
  static {
    System.out.println("Loading Candy");
  }
}

public class SweetShop {
  public static void main(String[] args) {
    System.out.println("inside main");
    new Candy(); // static method class
    System.out.println("After creating Candy");
    try {
      Class.forName("Gum"); // [1]
    } catch (ClassNotFoundException e) {
      System.out.println("Couldn't find Gum");
    }
    System.out.println("After Class.forName(\"Gum\")");
    new Cookie();
    System.out.println("After creating Cookie");
  }
}
/* 
execute
$ ./gradlew :typeinfo:SweetShop

Output:
inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie
*/

when run above example in Eclipse, [1] will throw ClassNotFoundException

 

    /**
     * Returns the {@code Class} object associated with the class or
     * interface with the given string name.  Invoking this method is
     * equivalent to:
     *
     * <blockquote>
     *  {@code Class.forName(className, true, currentLoader)}
     * </blockquote>
     *
     * where {@code currentLoader} denotes the defining class loader of
     * the current class.
     *
     * <p> For example, the following code fragment returns the
     * runtime {@code Class} descriptor for the class named
     * {@code java.lang.Thread}:
     *
     * <blockquote>
     *   {@code Class t = Class.forName("java.lang.Thread")}
     * </blockquote>
     * <p>
     * A call to {@code forName("X")} causes the class named
     * {@code X} to be initialized.
     *
     * @param      className   the fully qualified name of the desired class.
     * @return     the {@code Class} object for the class with the
     *             specified name.
     * @exception LinkageError if the linkage fails
     * @exception ExceptionInInitializerError if the initialization provoked
     *            by this method fails
     * @exception ClassNotFoundException if the class cannot be located
     */
    @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        return forName0(className, true,
                        ClassLoader.getClassLoader(Reflection.getCallerClass()));
    }

Basically, the @CallerSensitive annotation is used by the JVM

The JVM will track this annotation and, optionally, enforce the invariant that the sun.reflect.Reflection.getCallerClass method can only report the caller of a method when that method is marked with this annotation.

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/SweetShop.java

3. https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-

4. https://stackoverflow.com/questions/22626808/what-does-the-sun-reflect-callersensitive-annotation-mean

5. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Class.java

内容概要:本文档介绍了基于3D FDTD(时域有限差分)方法在MATLAB平台上对微带线馈电的矩形天线进行仿真分析的技术方案,重点在于模拟超MATLAB基于3D FDTD的微带线馈矩形天线分析[用于模拟超宽带脉冲通过线馈矩形天线的传播,以计算微带结构的回波损耗参数]宽带脉冲信号通过天线结构的传播过程,并计算微带结构的回波损耗参数(S11),以评估天线的匹配性能和辐射特性。该方法通过建立三维电磁场模型,精确求解麦克斯韦方程组,适用于高频电磁仿真,能够有效分析天线在宽频带内的响应特性。文档还提及该资源属于一个涵盖多个科研方向的综合性MATLAB仿真资源包,涉及通信、信号处理、电力系统、机器学习等多个领域。; 适合人群:具备电磁场与微波技术基础知识,熟悉MATLAB编程及数值仿真的高校研究生、科研人员及通信工程领域技术人员。; 使用场景及目标:① 掌握3D FDTD方法在天线仿真中的具体实现流程;② 分析微带天线的回波损耗特性,优化天线设计参数以提升宽带匹配性能;③ 学习复杂电磁问题的数值建模与仿真技巧,拓展在射频与无线通信领域的研究能力。; 阅读建议:建议读者结合电磁理论基础,仔细理解FDTD算法的离散化过程和边界条件设置,运行并调试提供的MATLAB代码,通过调整天线几何尺寸和材料参数观察回波损耗曲线的变化,从而深入掌握仿真原理与工程应用方法。
<think>好的,我需要分析用户提供的`rt_object_init`函数的代码,并生成一个符合要求的回答。首先,我需要理解这个函数的作用和各个部分的功能。函数的主要目的是初始化一个对象并将其添加到RT-Thread的对象管理系统中。参数包括对象指针、类型和名称。 接下来,我需要逐行解析代码。函数开始时获取对象信息,检查类型是否有效。然后进入临界区,遍历对象列表确保没有重复对象。退出临界区后,设置对象类型和名称,调用钩子函数,最后将对象插入到对应的链表中。 用户可能希望了解这个函数的具体实现细节,比如如何处理临界区保护、对象名称的复制、以及如何插入到链表中。同时,用户可能对相关问题感兴趣,例如如何查找对象、如何释放资源、如何避免重复初始化等。 需要注意的是,回答必须包含代码示例,并且在末尾列出3-5个相关问题。还要确保格式正确,使用中文,并且不使用Markdown。此外,要检查是否有遗漏的步骤或潜在的问题,比如断言的用途、钩子函数的作用等。 最后,确保相关问题覆盖函数的关键点,如对象查找、动态分配、钩子函数、类型错误的影响以及内存管理。这样用户可以在回答后进一步探索相关主题。</think>以下是 `rt_object_init` 函数的详细解析及其关键实现逻辑: --- ### **函数功能** 此函数用于初始化 RT-Thread 对象(如线程、信号量等)并注册到系统对象管理器,确保对象能被操作系统统一管理。 --- ### **代码解析** ```c void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name) { register rt_base_t temp; struct rt_list_node *node = RT_NULL; struct rt_object_information *information; // 1. 获取对象类型对应的信息结构体 information = rt_object_get_information(type); RT_ASSERT(information != RT_NULL); // 断言检查类型有效性 // 2. 临界区保护:防止并发访问 rt_enter_critical(); // 关闭中断 for (node = information->object_list.next; node != &(information->object_list); node = node->next) { struct rt_object *obj; obj = rt_list_entry(node, struct rt_object, list); RT_ASSERT(obj != object); // 确保无重复对象 } rt_exit_critical(); // 开启中断 // 3. 初始化对象参数 object->type = type | RT_Object_Class_Static; // 设置对象类型(含静态标志) rt_strncpy(object->name, name, RT_NAME_MAX); // 复制名称(确保唯一性) // 4. 调用对象附加钩子函数(调试/监控用途) RT_OBJECT_HOOK_CALL(rt_object_attach_hook, (object)); // 5. 临界区插入对象到全局链表 temp = rt_hw_interrupt_disable(); // 关闭中断 rt_list_insert_after(&(information->object_list), &(object->list)); rt_hw_interrupt_enable(temp); // 开启中断 } ``` --- ### **关键实现逻辑** 1. **对象类型验证** - 通过 `rt_object_get_information` 获取类型对应的 `rt_object_information` 结构体。 - 若类型无效(如 `NULL`),断言失败,防止非法初始化。 2. **并发安全检查** - 在临界区遍历对象链表,确保当前对象未被注册(防止重复初始化)。 - 使用 `rt_enter_critical`/`rt_exit_critical` 保护链表操作。 3. **对象属性设置** - 将对象类型与 `RT_Object_Class_Static` 标志位组合,标记为静态分配。 - 通过 `rt_strncpy` 安全复制名称,长度限制为 `RT_NAME_MAX`(通常为 16 字符)。 4. **钩子函数调用** - `rt_object_attach_hook` 用于调试或监控对象生命周期(如内存泄漏检测)。 5. **链表插入操作** - 在禁用中断下将对象插入到 `information->object_list` 链表尾部,确保线程安全。 --- ### **示例场景** ```c // 初始化一个信号量对象 rt_sem_t my_sem; rt_object_init(&my_sem, RT_Object_Class_Semaphore, "sem1"); // 后续操作:使用 rt_sem_init 完整初始化信号量 rt_sem_init(&my_sem, "sem1", 1, RT_IPC_FLAG_FIFO); ``` --- ### **注意事项** 1. **内存分配责任**:开发者需自行分配 `object` 内存(静态变量或 `rt_malloc`)。 2. **名称唯一性**:若同名对象已存在,`rt_object_init` 会触发断言失败。 3. **静态 vs 动态**:`RT_Object_Class_Static` 标志表示对象为静态分配,后续需调用 `rt_object_detach` 释放。 --- ### **潜在问题** - **重复初始化**:若对象未正确释放即再次初始化,可能导致链表异常- **中断嵌套**:`rt_hw_interrupt_disable` 可能引发中断嵌套问题(需工具链支持)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值