一.引入

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

二.创建package-info.java

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

三.package-info.java的作用

  1. "Package annotations must be in file package-info.java",package-info.java为我们提供了包注解的地方。JyzTargetPackage(http://zy19982004.iteye.com/blog/1979208)苦苦寻找终于找到地方了。
  2. 提供包级别的类(或接口),这些类(或接口)只有本包里才能访问,即使是子包也不能访问。
  3. 提供包的整体注释说明。

package-info.java

  1. /**
  2. * <b>package-info不是平常类,其作用有三个:</b><br>
  3. * 1、为标注在包上Annotation提供便利;<br>
  4. * 2、声明包的私有类和常量;<br>
  5. * 3、提供包的整体注释说明。<br>
  6. *
  7. * @author JoyoungZhang@gmail.com
  8. */
  9. @JyzTargetPackage(version="1.0")
  10. package com.jyz.study.jdk.annotation;
  11. class PackageInfo{
  12. public void common(){
  13. System.out.println("sa");
  14. }
  15. }
  16. class PackageInfoGeneric<T extends Throwable>{
  17. private T obj;
  18. public void set(T obj){
  19. this.obj = obj;
  20. }
  21. public void common(){
  22. System.out.println(obj + "sa");
  23. }
  24. }
  25. interface packageInfoInteger{
  26. public void test();
  27. }
  28. class PackageConstants{
  29. public static final String ERROE_CODE = "100001";
  30. }

TestPackageInfo.java

  1. package com.jyz.study.jdk.annotation;
  2. import java.io.IOException;
  3. /**
  4. * 测试package-info.java文件的作用
  5. * 1、为标注在包上Annotation提供便利;<br>
  6. * 2、声明包的私有类和常量;<br>
  7. * @author JoyoungZhang@gmail.com
  8. *
  9. */
  10. public class TestPackageInfo {
  11. public static void main(String[] args) {
  12. //1
  13. Package p = Package.getPackage("com.jyz.study.jdk.annotation");
  14. if(p != null && p.isAnnotationPresent(JyzTargetPackage.class)){
  15. JyzTargetPackage nav = p.getAnnotation(JyzTargetPackage.class);
  16. if(nav != null){
  17. System.out.println("package version:" + nav.version());
  18. }
  19. }
  20. //2
  21. PackageInfo packageInfo = new PackageInfo();
  22. packageInfo.common();
  23. //泛型也能很好的工作,在pakcage-info.java里定义的类和普通类没什么区别
  24. PackageInfoGeneric<Exception> packageInfoGeneric = new PackageInfoGeneric<Exception>();
  25. packageInfoGeneric.set(new IOException("device io"));
  26. packageInfoGeneric.common();
  27. Sub sub = new Sub();
  28. sub.test();
  29. System.out.println(PackageConstants.ERROE_CODE);
  30. }
  31. }
  32. class Sub implements packageInfoInteger{
  33. @Override
  34. public void test() {
  35. System.out.println("sub");
  36. }
  37. }
  38. console output:
  39. package version:1.0
  40. sa
  41. java.io.IOException: device iosa
  42. sub
  43. 100001

需要注意两点

  1. package-info.java里不能声明public class(或 interface)
  2. 刚开始p.isAnnotationPresent(JyzTargetPackage.class)返回false,后来找到原因JyzTargetPackage没有加上@Retention(RetentionPolicy.RUNTIME)。

@Inherited的使用

.@Inherited

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

二.代码

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Inherited
  4. public @interface DBTable {
  5. public String name() default "";
  6. }
  7. @Target(ElementType.TYPE)
  8. @Retention(RetentionPolicy.RUNTIME)
  9. public @interface DBTable2 {
  10. public String name() default "";
  11. }
  12. package com.jyz.study.jdk.reflect;
  13. import java.util.Arrays;
  14. import com.jyz.study.jdk.annotation.DBTable;
  15. import com.jyz.study.jdk.annotation.DBTable2;
  16. /**
  17. * 1.演示从Class对象上获得反射元素Field Method Constructor
  18. * 2.演示AnnotatedElement接口的四个方法
  19. * @author JoyoungZhang@gmail.com
  20. *
  21. */
  22. public class DeclaredOrNot {
  23. public static void main(String[] args) {
  24. Class<Sub> clazz = Sub.class;
  25. System.out.println("============================Field===========================");
  26. //public + 继承
  27. System.out.println(Arrays.toString(clazz.getFields()));
  28. //all + 自身
  29. System.out.println(Arrays.toString(clazz.getDeclaredFields()));
  30. System.out.println("============================Method===========================");
  31. //public + 继承
  32. System.out.println(Arrays.toString(clazz.getMethods()));
  33. //all + 自身
  34. System.out.println(Arrays.toString(clazz.getDeclaredMethods()));
  35. System.out.println("============================Constructor===========================");
  36. //public + 自身
  37. System.out.println(Arrays.toString(clazz.getConstructors()));
  38. //all + 自身
  39. System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));
  40. System.out.println("============================AnnotatedElement===========================");
  41. //注解DBTable2是否存在于元素上
  42. System.out.println(clazz.isAnnotationPresent(DBTable2.class));
  43. //如果存在该元素的指定类型的注释DBTable2,则返回这些注释,否则返回 null。
  44. System.out.println(clazz.getAnnotation(DBTable2.class));
  45. //继承
  46. System.out.println(Arrays.toString(clazz.getAnnotations()));
  47. //自身
  48. System.out.println(Arrays.toString(clazz.getDeclaredAnnotations()));
  49. }
  50. }
  51. @DBTable
  52. class Super{
  53. private int superPrivateF;
  54. public int superPublicF;
  55. public Super(){
  56. }
  57. private int superPrivateM(){
  58. return 0;
  59. }
  60. public int superPubliceM(){
  61. return 0;
  62. }
  63. }
  64. @DBTable2
  65. class Sub extends Super{
  66. private int subPrivateF;
  67. public int subPublicF;
  68. private Sub(){
  69. }
  70. public Sub(int i){
  71. }
  72. private int subPrivateM(){
  73. return 0;
  74. }
  75. public int subPubliceM(){
  76. return 0;
  77. }
  78. }
  79. console output:
  80. ============================Field===========================
  81. [public int com.jyz.study.jdk.reflect.Sub.subPublicF, public int com.jyz.study.jdk.reflect.Super.superPublicF]
  82. [private int com.jyz.study.jdk.reflect.Sub.subPrivateF, public int com.jyz.study.jdk.reflect.Sub.subPublicF]
  83. ============================Method===========================
  84. [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()]
  85. [private int com.jyz.study.jdk.reflect.Sub.subPrivateM(), public int com.jyz.study.jdk.reflect.Sub.subPubliceM()]
  86. ============================Constructor===========================
  87. [public com.jyz.study.jdk.reflect.Sub(int)]
  88. [private com.jyz.study.jdk.reflect.Sub(), public com.jyz.study.jdk.reflect.Sub(int)]
  89. ============================AnnotatedElement===========================
  90. true
  91. @com.jyz.study.jdk.annotation.DBTable2(name=)
  92. [@com.jyz.study.jdk.annotation.DBTable(name=), @com.jyz.study.jdk.annotation.DBTable2(name=)]
  93. [@com.jyz.study.jdk.annotation.DBTable2(name=)]

三.代码说明

  1. 代码演示了从Class对象上获得反射元素Field Method Constructor时get*和getDeclared*的区别。
  2. 代码演示了AnnotatedElement接口的四个方法。
    1. java.lang.reflect.AnnotatedElement表示可以被注解的元素。它只有四个方法,参考代码DeclaredOrNot.java。
    2. 当我使用clazz.getAnnotations()时,我期望得到控制台打印出来的内容,但实际上却只得到了[@com.jyz.study.jdk.annotation.DBTable2(name=)],后来发现是DBTable里没有声明@Inherited。

package-info.java的使用的更多相关文章

  1. paip.自动import的实现跟java.lang.SecurityException Prohibited package name java

    paip.自动import的实现跟java.lang.SecurityException Prohibited package name java #-----自动import 因为java.lang ...

  2. Java报错信息 java.lang.SecurityException: Prohibited package name: java.xxx

    package java.yun.System; public class SystemOut { public static void main(String[] args) { System.ou ...

  3. java classpath import package 机制 @Java的ClassPath, Package和Jar

    java classpath import package 机制   從一個簡單的例子談談package與import機制 基本原則:為什麼需要將Java文件和類文件切實安置到其所歸屬之Package ...

  4. 如何在命令提示符下编译运行含有Package的java文件

    这篇是大二自学Java的时候记下的笔记,中午回顾印象笔记的时候意外看到了这篇.看到多年前写下的文字,我想起那时候我对Java的懵懵懂懂,每天晚上在图书馆照着书写书上的示例代码,为一个中文分号绞尽脑汁, ...

  5. 手动编译含package的java源程序(包含外部包中定义的类)

    1)定义一个GSM类,如下: 包名是“SRC.GSM”,并且此程序引用了外部jar包.使用javac命令对GSM.java进行编译: GSM.java所在的文件夹如下所示: 切换到这个目录为当前工作目 ...

  6. [JAVA] 日常填坑 java.lang.SecurityException: Prohibited package name: java.xxx

    java虚拟机不允许包名以java开头. https://blog.csdn.net/sinat_28690417/article/details/72328547

  7. 使用junit单元测试,报Cannot instantiate test(s): java.lang.SecurityException: Prohibited package name: java.com.com.test

    在测试类中不能一级包名不能以java开头, 将包改为com.com.test就好了.

  8. Java的Package和Classpath

    Package 在Java中,Package是用来包含一系相关实例的集合.这些相关联的实例包括:类.接口.异常.错误以及枚举. Package主要有一些的几点作用: Package可以处理名字冲突,在 ...

  9. Java 包(package)详解

    为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包也采用了树形目录的存储方式.同一 ...

  10. package、import、java及javac的相关介绍(转)

    Package: package中所存放的文件 所有文件,不过一般分一下就分这三种 1.java程序源文件,扩展名为.java: 2.编译好的java类文件,扩展名为.class: 3.其他文件,也称 ...

随机推荐

  1. 中国 AI 天才养成计划:清华姚班和 100 个「张小龙」

    https://daily.zhihu.com/story/9653612?from=timeline&isappinstalled=0   AI财经社,专注未来,以及更好的生活 真正的 AI ...

  2. python语言学习--2

    第三天1. python代码缩进规则:具有相同缩进的代码被视为代码块,4个空格, 不要使用Tab,更不要混合Tab和空格,否则很容易造成因为缩进引起的语法错误. 2.list:[...] 用(名称任意 ...

  3. java基础(五) String性质深入解析

    引言   本文将讲解String的几个性质. 一.String的不可变性   对于初学者来说,很容易误认为String对象是可以改变的,特别是+链接时,对象似乎真的改变了.然而,String对象一经创 ...

  4. shell中的set、seq、eval、exec、&&和||

    一.set 查看set 帮助: bash -c "help set" 选项: -e:任何命令执行失败(非0 status)直接退出 -x: 打印执行过程的命令行.参数 +e:命令执 ...

  5. MySQL中lock tables和unlock tables浅析

    MySQL中lock tables和unlock tables浅析   在MySQL中提供了锁定表(lock tables)和解锁表(unlock tables)的语法功能,ORACLE与SQL Se ...

  6. spring4笔记----“零配置”:spring提供的几个Annotation标注

    @Component  :标注一个普通的Spring Bean类 @Controller    :标注一个控制器组件器 @Service        :标注一个业务逻辑组件器 @Repository ...

  7. mssql sqlserver SQL 位运算举例权限应用

    摘要: 下文通过举例的方式讲述sqlserver中位运算的相关知识,如下所示: 实验环境:sqlserver 2008 R2 在sqlserver的权限设置,我们通常使用1.2.4.8.16.32.6 ...

  8. python设计模式之单例模式(转)

    设计模式之单例模式 单例设计模式是怎么来的?在面向对象的程序设计中,当业务并发量非常大时,那么就会出现重复创建相同的对象,每创建一个对象就会开辟一块内存空间,而这些对象其实是一模一样的,那么有没有办法 ...

  9. python爬虫工程师各个阶段需要掌握的技能和知识介绍

    本文主要介绍,想做一个python爬虫工程师,或者也可以说是,如何从零开始,从初级到高级,一步一步,需要掌握哪些知识和技能. 初级爬虫工程师: Web前端的知识:HTML, CSS, JavaScri ...

  10. 编写脚本实现DHCP服务与DHCP中继自动化执行

    编写脚本实现DHCP服务与DHCP中继自动化执行 本脚本是在liunx搭建DHCP服务器以及DHCP中继服务器实验环境下实现的https://www.cnblogs.com/yuzly/p/10539 ...