一文带你看懂:不为人知的 package-info.java 文件

许多同学日常开发时,都不太注意到,原来自己维护这么久的 web 工程中,居然还有 package-info.java 这么一个类。

但只要我们在 idea 中搜索一下,就能够发现很多依赖包,都用到了这个类的实现。

1f1fd46eeb61f3798bafa499b7b2ddc0.png

那么,下面我们一起研究下,到底什么是 package-info.java 类文件~~

【目录】

1)注解技术

2)package-info类拆解

3)动态ClassLoader原理 与 双亲委派机制

4)自定义ClassLoader

一、注解技术

注解(annotation)是 Java 5 引入的,用来为类、方法、字段、参数等 Java 结构提供额外信息的机制。我先举个例子,比如,Java 核心类库中的@Override注解是被用来声明某个实例方法重写了父类的同名同参数类型的方法。

package java.lang;


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

二、package-info类拆解

f20e72e21123f9b2324ec504aab2a243.png

下面我们用一个简单的例子(分包逻辑开发),演示 package-info.java 的用法:

1)创建一个package:packageinfo

2)创建一个注解:PackageAnotation

/**
 * PackageAnotation.java 定义修饰包的注解
 * <b>package-info不是平常类,其作用有三个:</b><br>
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * 3、提供包的整体注释说明。<br>
 */
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
@interface PackageAnotation {
  public String version() default "";
}

3)创建一个类,类名 = package-info.java

/**
 * <b>package-info不是平常类,其作用有三个:</b><br>
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * 3、提供包的整体注释说明。<br>
 */
@PackageAnotation(version="1.0")
package packageinfo;

4)创建测试用例,类名 = TestPackageInfo.java

package packageinfo;


/**
 * 测试package-info.java文件的作用
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * @author JoyoungZhang@gmail.com
 */
public class TestPackageInfo {
    public static void main(String[] args) {  
        //1 获取 Package 类
        Package p = Package.getPackage("packageinfo");
        //2 判断这个包对象,(是否在 package-info.java 中声明)且被某个注解(PackageAnotation)修饰
        if(p != null && p.isAnnotationPresent(PackageAnotation.class)) {
            //3 如果找到了注解,获取注解信息,实现业务逻辑(Servlet过滤、鉴权、分发请求等)
            PackageAnotation nav = p.getAnnotation(PackageAnotation.class);
            if (nav != null) {
                System.out.println("package version:" + nav.version());
            }
        }
    }
}

三、动态ClassLoader原理 与 双亲委派机制

3.1、动态ClassLoader原理

上面的测试用例,Package.getPackage("packageinfo"); 背后隐藏了一个原理 -- 类的动态加载。

写好一个Java程序,都是由若干个.class文件组织而成的一个完整的Java应用程序。当程序在运行时,即会调用该程序的一个入口函数,通过它来调用系统的相关功能;而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另外一个class文件中的方法。因此,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是按需通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,从而只有class文件被载入到了内存之后,才能被其它class所引用。

所以ClassLoader就是用来动态加载class文件到内存当中用的。

b2953f014d4abdbba60fe6cabaf63d8c.png

我们写好的应用类(业务代码),大部分都是通过这个类加载器 AppClassLoader 来加载到JVM里面。

3.2 JVM默认有3个默认类加载器

3.2.1 AppClassLoader

AppClassLoader 称为应用类加载器,又称为系统类加载器,负责在JVM启动时,加载来自在命令java中的classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR包和类路径。

3.2.2 ExtClassLoader

ExtClassLoader 称为扩展类加载器,主要负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包或者由java.ext.dirs系统属性指定的jar包.放入这个目录下的jar包对AppClassLoader加载器都是可见的(因为ExtClassLoader是AppClassLoader的父加载器,并且Java类加载器采用了委托机制)。

3.2.3 BootstrapClassLoader

BootstrapClassLoader 称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件。

3.3 双亲委派机制

如果说,我们想引用一些外部依赖,那么就需要更高层的类加载器,让它们帮我们完成这个类装载的过程了,而这个过程也有个专有名词:双亲委派机制。

类加载分级:

-> 自定义ClassLoader

-> AppClassLoader

-> ExtClassLoader

-> BootstrapClassLoader

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托交给父类加载器,父类加载器又将加载任务向上委托,直到最父类加载器,如果最父类加载器可以完成类加载任务,就成功返回,如果不行就向下传递委托任务,由其子类加载器进行加载。

7411df290ed993acaba5687e72d0d8d1.png

1d53c72f0682f7bae60f71a9f52c7489.png

总结

以上是关于package-info.java的相关知识介绍,还牵扯到了类加载器的回顾,希望对大家工作有所帮助。

6cdaf23d4175abb8224f75a832750f54.png

后端技术&架构精华

2ce185a1e9804eb2e8b1e14a49e8ec07.png

《源码系列》

JDK之Object 类

JDK之BigDecimal 类

JDK之String 类

JDK之Lambda表达式

Spring源码:Event事件发布与监听

《经典书籍》

Java并发编程实战:第1章 多线程安全性与风险

Java并发编程实战:第2章 影响线程安全性的原子性和加锁机制

Java并发编程实战:第3章 助于线程安全的三剑客:final & volatile & 线程封闭

《服务端技术栈》

《Docker 核心设计理念

《Kafka史上最强原理总结》

《HTTP的前世今生》

《算法系列》

读懂排序算法(一):冒泡&直接插入&选择比较

《读懂排序算法(二):希尔排序算法》

《读懂排序算法(三):堆排序算法》

《读懂排序算法(四):归并算法》

《读懂排序算法(五):快速排序算法》

《读懂排序算法(六):二分查找算法》

《项目管理》

《学点项目管理,对咱程序员很重要》

《项目管理实践篇(一):技术人如何做好风险把控》

《项目管理实践篇(二):总结项目经历》

《如何写好一篇汇报材料》

<think>好的,我现在需要帮助用户寻找关于ORB-SLAM3的封装或集成方案。首先,用户的问题是关于ORB-SLAM3的wrapper实现和集成解决方案。我需要先理解ORB-SLAM3的基本情况,以及常见的封装和集成方法。 ORB-SLAM3是一个功能强大的视觉SLAM系统,支持单目、双目和RGB-D相机,还具备IMU融合的能力。封装或集成方案通常是为了方便将ORB-SLAM3嵌入到不同的应用中,比如机器人、AR/VR或者自动驾驶系统中。用户可能需要将ORB-SLAM3与其他库或框架结合使用,或者简化其接口以便调用。 接下来,我应该考虑现有的解决方案。首先,官方资源是基础,用户可能已经看过官方仓库,但可能没有找到足够的封装示例。然后是第三方封装库,比如GitHub上的orb_slam3_ros,这可能是一个ROS封装,适合机器人应用。另外,ROS集成是常见的需求,很多SLAM系统都会提供ROS节点,方便与其他模块通信。 Python封装也是一个方向,因为有些开发者习惯用Python进行快速开发。可能存在基于C++和Python绑定的项目,比如使用pybind11或Boost.Python。此外,Docker容器化部署也是一个趋势,可以解决环境依赖的问题,方便在不同系统上部署。 硬件平台集成也是需要考虑的,比如NVIDIA Jetson或树莓派,用户可能需要在嵌入式设备上运行ORB-SLAM3,这时候需要优化和特定的接口。还有多传感器融合的集成,比如结合IMU、激光雷达等,可能需要额外的封装工作。 然后,我应该考虑具体的实现步骤,比如封装核心功能、定义接口、处理多线程和回调机制,以及数据格式转换。例如,将ORB-SLAM3的位姿输出转换为ROS中的TF消息,或者将图像数据从OpenCV格式转换为ROS的sensor_msgs/Image。 可能还需要提到现有的项目或案例,比如ROS中的orb_slam3_ros包,或者某些GitHub仓库提供的Python接口。同时,应该提醒用户注意性能优化,尤其是在实时系统中,资源管理很重要。 最后,生成相关问题需要考虑用户可能的后续需求,比如如何优化性能,如何集成到特定框架,如何处理多传感器数据,或者如何部署在嵌入式设备上。这些问题可以帮助用户进一步探索ORB-SLAM3的应用。</think>### ORB-SLAM3封装与集成方案 ORB-SLAM3是一个支持单目、双目、RGB-D和IMU的多功能SLAM系统[^1],其封装和集成需结合具体应用场景。以下是常见方案: --- #### 1. **官方资源与基础集成** - **源码仓库**:从[ORB-SLAM3官方GitHub仓库](https://github.com/UZ-SLAMLab/ORB_SLAM3)获取代码,支持直接编译为库文件(`.so`或`.a`)。 - **核心功能调用**:通过C++接口调用SLAM初始化、图像输入和位姿输出。 ```cpp ORB_SLAM3::System SLAM(argv[1], argv[2], ORB_SLAM3::System::MONOCULAR, true); cv::Mat pose = SLAM.TrackMonocular(im, timestamp); ``` --- #### 2. **ROS封装方案** - **ROS节点化**:将ORB-SLAM3封装为ROS节点,订阅图像话题并发布位姿和地图。 - 示例仓库:[orb_slam3_ros](https://github.com/jhzhao0607/orb_slam3_ros) - 数据流: ``` 摄像头驱动 → ROS Image消息 → ORB-SLAM3节点 → 发布TF和Map消息 ``` - **关键接口**: ```cpp // 订阅图像话题 image_sub = nh.subscribe("/camera/image_raw", 1, &ImageGrabber::GrabImage, &igb); // 发布相机位姿 pose_pub = nh.advertise<geometry_msgs::PoseStamped>("slam_pose", 1); ``` --- #### 3. **Python封装(基于C++绑定)** 使用`pybind11`或`Boost.Python`暴露C++接口: ```cpp #include <pybind11/pybind11.h> PYBIND11_MODULE(orb_slam3, m) { m.def("initialize", &ORB_SLAM3::System::System); m.def("track_image", &ORB_SLAM3::System::TrackMonocular); } ``` 调用示例(Python): ```python import orb_slam3 slam = orb_slam3.initialize("vocab.yaml", "config.yaml") pose = slam.track_image(image_array, timestamp) ``` --- #### 4. **Docker容器化部署** - **环境隔离**:通过Docker镜像解决依赖库(如OpenCV、Eigen3)版本冲突问题。 - 示例`Dockerfile`: ```dockerfile FROM ubuntu:20.04 RUN apt-get install -y libopencv-dev libeigen3-dev COPY ORB_SLAM3 /app WORKDIR /app RUN ./build.sh ``` --- #### 5. **硬件平台适配** - **嵌入式设备**:针对NVIDIA Jetson或树莓派优化线程管理和计算资源分配。 - **FPGA加速**:通过HLS(高层次综合)将特征提取模块(ORB)移植到FPGA。 --- #### 6. **多传感器融合集成** - **IMU融合**:启用`ORB_SLAM3::System::IMU_MONOCULAR`模式,输入图像和IMU数据同步队列。 - **激光雷达扩展**:将3D点云与ORB特征地图对齐(需自定义ICP模块)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后台技术汇

对你的帮助,是对我的最好鼓励。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值