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

内容概要:本文提出了一种基于融合鱼鹰算法和柯西变异的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的参数,进而结合卷积神经网络(CNN)与双向长短期记忆网络(BiLSTM)构建OCSSA-VMD-CNN-BILSTM模型,实现对轴承故障的高【轴承故障诊断】基于融合鱼鹰和柯西变异的麻雀优化算法OCSSA-VMD-CNN-BILSTM轴承诊断研究【西储大学数据】(Matlab代码实现)精度诊断。研究采用西储大学公开的轴承故障数据集进行实验验证,通过优化VMD的模态数和惩罚因子,有效提升了信号分解的准确性与稳定性,随后利用CNN提取故障特征,BiLSTM捕捉时间序列的深层依赖关系,最终实现故障类型的智能识别。该方法在提升故障诊断精度与鲁棒性方面表现出优越性能。; 适合人群:具备一定信号处理、机器学习基础,从事机械故障诊断、智能运维、工业大数据分析等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决传统VMD参数依赖人工经验选取的问题,实现参数自适应优化;②提升复杂工况下滚动轴承早期故障的识别准确率;③为智能制造与预测性维护提供可靠的技术支持。; 阅读建议:建议读者结合Matlab代码实现过程,深入理解OCSSA优化机制、VMD信号分解流程以及CNN-BiLSTM网络架构的设计逻辑,重点关注参数优化与故障分类的联动关系,并可通过更换数据集进一步验证模型泛化能力。
<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` 可能引发中断嵌套问题(需工具链支持)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值