在看spring源码的是否发现了以下代码,package-info.java,奇怪的是没有类,没有方法,不知道什么用处。

/**
 * Classes supporting the org.springframework.context package,
 * such as abstract base classes for ApplicationContext
 * implementations and a MessageSource implementation.
 */
@NonNullApi  用于声明参数和返回值在默认情况下对于给定的包被视为不可为空。
@NonNullFields 用于声明对于给定的包,默认情况下字段将被视为不可为空
package org.springframework.context.support;

import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

package-info.java有什么用

三个作用:

1. 为标注在包上的注解Annotation提供便利。
2. 声明友好类和包常量。
3. 提供包的整体注释说明。

1、为标注在包上的注解提供便利

先定义一个只能标注在包上的注解

@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PkgAnnotation {}

再定义一个package-info类

@PkgAnnotation
package com.company;

main方法

public class Client {
    public static void main(String[] args) {
        
        Package pkg = Package.getPackage("com.company");
        Annotation[] annotations = pkg.getAnnotations();
        
        for(Annotation an : annotations) {
            if(an instanceof PkgAnnotation) {
                System.out.println("我是一个PkgAnnotation注解");
            }
        }
    }
}

结果:

我是一个PkgAnnotation注解

结论:

我们可以统一处理该注解包下的所有类,比如初始化,检查等等。

类似Struts的@Namespace,可以放在包名上,标注一个包的namespace路径。

我们想指定某个Spring项目的其中一个Java包中所有类和接口的成员变量都是非空的,就可以用的spring-core库的@NonNullFields注解。

  • @NonNullApi 用于声明参数和返回值在默认情况下对于给定的包被视为不可为空。
  • @NonNullFields 用于声明对于给定的包,默认情况下字段将被视为不可为空

但是请注意,上述提到的@NonNullApi@NonNullFields都是Spring 5的spring-core库引入的 jsr-305注解,需要额外添加com.google.code.findbugs:jsr305:3.0.2依赖项,否则将无法使用这些注解。

Spring官方文档-空安全》文章中也提到:

没有必要也不推荐将JSR-305依赖项添加到项目中来利用Spring空安全注释。只有像基于Spring的库的项目,即在代码库中使用空安全注释的项目才应该添加com.google.code.findbugs:jsr305:3.0.2依赖项来避免编译警告。

2、声明友好类和包常量

  • 提供包级别的常量:

package-info.java 中只能声明 default 默认访问权限的类,只能包内访问,其它包包括子包都不可访问。

package com.test;

class Constant {
	static final String PACKAGE_NAME = "Test";
}
  • 友好类
package com.test;

class PkgClass {
	public void test();
}

调用的时候需要在同包下

public class Application {
    public static void main(String[] args) {
        System.out.println(Constant.PACKAGE_NAME);
        
    }
}

如何创建package-info.java

在项目中使用创建类的方式(Java Class)是无法直接创建的,会报“Type name is not valid”错误。

想创建也很简单,我们应当对任意包文件夹鼠标右键再依次选中"New"-"File""New"-"package-info.java",这样既可成功创建一个package-info.java文件: