package-info.java_package-info.java的使用

本文详细介绍了如何创建和使用package-info.java文件,以及它在Java包注解、包级别访问控制和整体注释说明中的作用。通过示例展示了如何定义和使用自定义注解,如@JyzTargetPackage,并解释了注解的保留策略和继承性。同时,通过代码演示了反射中get*和getDeclared*的区别以及AnnotatedElement接口的方法。
摘要由CSDN通过智能技术生成

一.引入

上文中,提到了注解类JyzTargetPackage可以定义为@Target(ElementType.PACKAGE),可是在被注解类里我无论怎么加,编译器都报错,于是引入了package-info.java这个文件。

二.创建package-info.java

"I found that when you create a new package in eclispe there is a check box to check if you want a package-info.java."勾上就行了。

b39af1120b372111bbdfe7b4f28bd8bb.png

如果不幸的是你已经创建了这个包并在里面定义了很多类,而eclispe又是不能直接创建一个package-info.java文件的。只能在包对应文件夹里,手动创建一个package-info.java,写上包名,最后刷新eclispe即可。

三.package-info.java的作用

"Package annotations must be in file package-info.java",package-info.java为我们提供了包注解的地方。JyzTargetPackage(http://zy19982004.iteye.com/blog/1979208)苦苦寻找终于找到地方了。

提供包级别的类(或接口),这些类(或接口)只有本包里才能访问,即使是子包也不能访问。

提供包的整体注释说明。

bc481303751a8b84955c60543a8a3733.png

package-info.java

Java代码  c6c19216b4d286d2766e5ce234f2468b.png

/**

package-info不是平常类,其作用有三个:

* 1、为标注在包上Annotation提供便利;

* 2、声明包的私有类和常量;

* 3、提供包的整体注释说明。

*

* @author JoyoungZhang@gmail.com

*/

@JyzTargetPackage(version="1.0")

package com.jyz.study.jdk.annotation;

class PackageInfo{

public void common(){

System.out.println("sa");

}

}

class PackageInfoGeneric{

private T obj;

public void set(T obj){

this.obj = obj;

}

public void common(){

System.out.println(obj + "sa");

}

}

interface packageInfoInteger{

public void test();

}

class PackageConstants{

public static final String ERROE_CODE = "100001";

}

TestPackageInfo.java

Java代码  c6c19216b4d286d2766e5ce234f2468b.png

package com.jyz.study.jdk.annotation;

import java.io.IOException;

/**

* 测试package-info.java文件的作用

* 1、为标注在包上Annotation提供便利;

* 2、声明包的私有类和常量;

* @author JoyoungZhang@gmail.com

*

*/

public class TestPackageInfo {

public static void main(String[] args) {

//1

Package p = Package.getPackage("com.jyz.study.jdk.annotation");

if(p != null && p.isAnnotationPresent(JyzTargetPackage.class)){

JyzTargetPackage nav = p.getAnnotation(JyzTargetPackage.class);

if(nav != null){

System.out.println("package version:" + nav.version());

}

}

//2

PackageInfo packageInfo = new PackageInfo();

packageInfo.common();

//泛型也能很好的工作,在pakcage-info.java里定义的类和普通类没什么区别

PackageInfoGeneric packageInfoGeneric = new PackageInfoGeneric();

packageInfoGeneric.set(new IOException("device io"));

packageInfoGeneric.common();

Sub sub = new Sub();

sub.test();

System.out.println(PackageConstants.ERROE_CODE);

}

}

class Sub implements packageInfoInteger{

@Override

public void test() {

System.out.println("sub");

}

}

console output:

package version:1.0

sa

java.io.IOException: device iosa

sub

100001

需要注意两点

package-info.java里不能声明public class(或 interface)

刚开始p.isAnnotationPresent(JyzTargetPackage.class)返回false,后来找到原因JyzTargetPackage没有加上@Retention(RetentionPolicy.RUNTIME)。

@Inherited:允许子类继承父类的注解。

二.代码

Java代码  c6c19216b4d286d2766e5ce234f2468b.png

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Inherited

public @interface DBTable {

public String name() default "";

}

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface DBTable2 {

public String name() default "";

}

package com.jyz.study.jdk.reflect;

import java.util.Arrays;

import com.jyz.study.jdk.annotation.DBTable;

import com.jyz.study.jdk.annotation.DBTable2;

/**

* 1.演示从Class对象上获得反射元素Field Method Constructor

* 2.演示AnnotatedElement接口的四个方法

* @author JoyoungZhang@gmail.com

*

*/

public class DeclaredOrNot {

public static void main(String[] args) {

Class clazz = Sub.class;

System.out.println("============================Field===========================");

//public + 继承

System.out.println(Arrays.toString(clazz.getFields()));

//all + 自身

System.out.println(Arrays.toString(clazz.getDeclaredFields()));

System.out.println("============================Method===========================");

//public + 继承

System.out.println(Arrays.toString(clazz.getMethods()));

//all + 自身

System.out.println(Arrays.toString(clazz.getDeclaredMethods()));

System.out.println("============================Constructor===========================");

//public + 自身

System.out.println(Arrays.toString(clazz.getConstructors()));

//all + 自身

System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));

System.out.println("============================AnnotatedElement===========================");

//注解DBTable2是否存在于元素上

System.out.println(clazz.isAnnotationPresent(DBTable2.class));

//如果存在该元素的指定类型的注释DBTable2,则返回这些注释,否则返回 null。

System.out.println(clazz.getAnnotation(DBTable2.class));

//继承

System.out.println(Arrays.toString(clazz.getAnnotations()));

//自身

System.out.println(Arrays.toString(clazz.getDeclaredAnnotations()));

}

}

@DBTable

class Super{

private int superPrivateF;

public int superPublicF;

public Super(){

}

private int superPrivateM(){

return 0;

}

public int superPubliceM(){

return 0;

}

}

@DBTable2

class Sub extends Super{

private int subPrivateF;

public int subPublicF;

private Sub(){

}

public Sub(int i){

}

private int subPrivateM(){

return 0;

}

public int subPubliceM(){

return 0;

}

}

console output:

============================Field===========================

[public int com.jyz.study.jdk.reflect.Sub.subPublicF, public int com.jyz.study.jdk.reflect.Super.superPublicF]

[private int com.jyz.study.jdk.reflect.Sub.subPrivateF, public int com.jyz.study.jdk.reflect.Sub.subPublicF]

============================Method===========================

[public int com.jyz.study.jdk.reflect.Sub.subPubliceM(), public int com.jyz.study.jdk.reflect.Super.superPubliceM(), public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]

[private int com.jyz.study.jdk.reflect.Sub.subPrivateM(), public int com.jyz.study.jdk.reflect.Sub.subPubliceM()]

============================Constructor===========================

[public com.jyz.study.jdk.reflect.Sub(int)]

[private com.jyz.study.jdk.reflect.Sub(), public com.jyz.study.jdk.reflect.Sub(int)]

============================AnnotatedElement===========================

true

@com.jyz.study.jdk.annotation.DBTable2(name=)

[@com.jyz.study.jdk.annotation.DBTable(name=), @com.jyz.study.jdk.annotation.DBTable2(name=)]

[@com.jyz.study.jdk.annotation.DBTable2(name=)]

三.代码说明

代码演示了从Class对象上获得反射元素Field Method Constructor时get*和getDeclared*的区别。

代码演示了AnnotatedElement接口的四个方法。java.lang.reflect.AnnotatedElement表示可以被注解的元素。它只有四个方法,参考代码DeclaredOrNot.java。

d3b1551a0fdcc60838906e0d1e9d6d70.png

当我使用clazz.getAnnotations()时,我期望得到控制台打印出来的内容,但实际上却只得到了[@com.jyz.study.jdk.annotation.DBTable2(name=)],后来发现是DBTable里没有声明@Inherited。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值