`

理解注解中的@Inherited

阅读更多
@Inherited:
   @Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。



注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,
      方法并不从它所重载的方法继承annotation。

  当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。
   如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:
   检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。


看下面的例子:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ATable {

	public String name() default "";
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BTable {
	public String name() default "";
}


@ATable
public class Super {
	private int superx;
	public int supery;
	public Super() {
	}
    private int superX(){  
        return 0;  
    }  
    public int superY(){  
        return 0;  
    }  
    
}


@BTable
public class Sub extends Super{
	private int subx;
	public int suby;
	private Sub()
	{  
	}  
    public Sub(int i){  
    }  
    private int subX(){  
        return 0;  
    }  
    public int subY(){  
        return 0;  
    }  
}



public class TestMain {
	public static void main(String[] args) {
		
		Class<Sub> clazz = Sub.class;
	    
		System.out.println("============================Field===========================");  
		System.out.println(Arrays.toString(clazz.getFields()));
        System.out.println(Arrays.toString(clazz.getDeclaredFields()));  //all + 自身  
        System.out.println("============================Method===========================");
        System.out.println(Arrays.toString(clazz.getMethods()));   //public + 继承  
        //all + 自身  
        System.out.println(Arrays.toString(clazz.getDeclaredMethods()));
        System.out.println("============================Constructor===========================");  
        System.out.println(Arrays.toString(clazz.getConstructors()));  
                System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));  
        System.out.println("============================AnnotatedElement===========================");  
        //注解DBTable2是否存在于元素上  
        System.out.println(clazz.isAnnotationPresent(BTable.class));  
        //如果存在该元素的指定类型的注释DBTable2,则返回这些注释,否则返回 null。  
        System.out.println(clazz.getAnnotation(BTable.class));  
        //继承  
        System.out.println(Arrays.toString(clazz.getAnnotations()));  
        System.out.println(Arrays.toString(clazz.getDeclaredAnnotations()));  ////自身  
	}
}



分析下这段代码,这里定义了两个annotion,其中ATable使用了@Inherited, BTable没有使用
@Inherited,类Super和类Sub分别使用了ATable和BTable这两个注解,并且Sub类 继承Super类。


这段程序的运行结果如下:
============================Field===========================
[public int annotion.inherit.Sub.suby, public int annotion.inherit.Super.supery]
[private int annotion.inherit.Sub.subx, public int annotion.inherit.Sub.suby]
============================Method===========================
[public int annotion.inherit.Sub.subY(), public int annotion.inherit.Super.superY(), 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 final native void java.lang.Object.wait(long) 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 annotion.inherit.Sub.subX(), public int annotion.inherit.Sub.subY()]
============================Constructor===========================
[public annotion.inherit.Sub(int)]
[private annotion.inherit.Sub(), public annotion.inherit.Sub(int)]
============================AnnotatedElement===========================
true
@annotion.inherit.BTable(name=)
[@annotion.inherit.ATable(name=), @annotion.inherit.BTable(name=)]
[@annotion.inherit.BTable(name=)]




getFields()获得某个类的所有的公共(public)的字段,包括父类。
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,
但是不包括父类的申明字段。 同样类似的还有getConstructors()和getDeclaredConstructors(),
getMethods()和getDeclaredMethods()。

因此:Field的打印好理解,因为sub是super类的子类,会继承super的类
同样method和constructor的打印也是如此。

clazz.getAnnotations()可以打印出当前类的注解和父类的注解
clazz.getDeclaredAnnotations()只会打印出当前类的注解

如果注解ATable把@Inherit去掉。那么后面四行的输出结果为:
true
@annotion.inherit.BTable(name=)
[@annotion.inherit.BTable(name=)]
[@annotion.inherit.BTable(name=)]

无法获取到@ATable的注解,
也就是说注解和普通类的区别是如果一个子类想获取到父类上的注解信息,
那么必须在父类上使用的注解上面 加上@Inherit关键字




分享到:
评论
1 楼 Dom_4j 2018-01-28  

相关推荐

    Android注解基础介绍快速入门与解读

    【Android注解基础介绍快速入门与解读】 ...理解并熟练运用元注解和自定义注解,能够帮助开发者编写出更加高效、可维护的Android应用。在实际开发中,应根据需求合理选择和创建注解,以实现最佳的代码设计和优化。

    Java元注解.docx

    理解并熟练运用这些元注解是深入掌握Java注解的关键,它们可以帮助我们更好地定制和控制注解的行为,从而提高代码的可读性、可维护性和可扩展性。在实际开发中,可以根据需求选择合适的元注解,优化代码结构和功能。

    疯狂java讲义29 电子版 pdf

    通过对比图14.2和图14.3中的API文档效果,我们可以看到带有@Documented注解的元素在文档中的体现,以及删除或注释掉相关代码后,注解信息不再出现在文档中,进而理解了@Documented注解的实际效果和重要性。...

    31.1、自定义注解1

    在Java编程语言中,注解(Annotation)是一种元编程机制,允许程序员在源代码中插入额外的信息,这些信息可以被编译器或者运行时环境用来处理代码。自定义注解是扩展这一机制的一种方式,允许开发者创建自己的注解...

    Java中三种标准注解和四种元注解.pdf

    Java中的注解是一种强大的工具,它允许程序员在代码中嵌入元数据,这些信息可以用于编译时检查、运行时处理或文档生成等目的。Java提供了三种标准注解...理解并熟练使用Java的注解和元注解是现代Java开发中的必备技能。

    详解JDK 5 Annotation 注解之@Target的用法介绍

    在Java编程语言中,注解(Annotation)是一种元数据,它提供了一种安全的方法来关联信息于程序元素,如类、方法、变量等,而这些信息可以...在实际开发中,理解并熟练运用 `@Target` 是使用Java注解不可或缺的一部分。

    注解与反射高效开发法.pdf

    @Documented注解可以使得使用它的注解能够被javadoc工具提取成文档,@Inherited则允许子类继承父类中的注解。 @Target注解用于限制注解可以被应用到哪些元素上,可以应用于注解类型、构造函数、字段或属性、局部...

    Java注解之Retention、Documented、Inherited介绍

    在Java中,注解有三种关键特性:Retention、Documented和Inherited,它们分别控制注解的生命周期、文档化和继承性。 1. **Retention(保留)** Retention注解用于定义一个注解的生存周期,即在程序的哪个阶段仍然...

    (转)Java中的注解是如何工作的?

    Java中的注解(Annotation)是元数据的一种形式,它提供了在代码中嵌入信息的方式,这些信息可以被编译器、构建工具或者运行时环境读取和处理。注解不仅有助于提升代码的可读性和可维护性,还能帮助开发者实现自动化...

    注解+自定义注解+元注解+理解

    本文将深入探讨注解、自定义注解、元注解及其理解。 一、注解的基本概念 1.1 注解的作用 注解的主要作用是为编译器或运行时环境提供信息,使得开发者能够简化代码,减少样板代码,提高代码的可读性和可维护性。...

    第十八章 Spring 注解(Annotations)1

    Spring 注解是Spring框架中的一个重要组成部分,它极大地简化了配置并推动了声明式编程的发展。在Spring框架的历史中,注解...对于Spring框架的学习者来说,理解和实践这些注解是深入理解Spring生态系统的关键步骤。

    spring中注解的实现原理

    元注解是用于创建其他注解的注解,如`@Target`、`@Retention`、`@Documented`和`@Inherited`,它们定义了注解的使用位置、生命周期、是否出现在Javadoc中以及是否能被子类继承。例如,`@Component`就是一个元注解,...

    JAVA 注解示例 详解

    在实际开发中,理解并熟练运用Java注解能够提高代码的可读性,减少错误,并简化许多自动化任务。通过合理地创建和使用注解,我们可以让代码更易于维护,同时也为工具和框架提供更多的灵活性和扩展性。因此,学习和...

    java元注解的介绍说明

    理解并熟练运用元注解是提升Java编程能力的关键步骤之一,它们是Java语言中的一种强大工具,可以极大地提高代码的灵活性和可维护性。通过实际的编程练习和示例,开发者可以深入理解这些元注解的工作原理,并将其有效...

    自定义注解案例

    在Java编程语言中,自定义注解是一种强大的工具,它允许程序员定义自己的元数据,以提供额外的信息给编译器、运行时环境或其他工具。...通过研究这个案例,你将更深入地理解自定义注解在实际项目中的工作原理和用途。

    Spring java注解,元注解和自定义注解

    ### Spring Java注解、元注解与自定义注解详解 #### 一、Java注解简介 在深入了解Spring框架中的注解应用之前,我们首先需要对Java注解有一个基本的认识。...希望本文能帮助读者更好地理解和运用Spring中的注解技术。

    Java注解编程1

    Java注解编程是Java语言的一种重要特性,引入于JDK1.5,它允许...理解并熟练运用注解,对于理解和编写现代Java应用程序至关重要。通过自定义注解,开发者可以创建自己的元数据系统,进一步提高代码的灵活性和可扩展性。

    Java自定义注解实例

    Java自定义注解是Java编程语言中的一个重要特性,它允许程序员在代码中插入元数据,这些元数据可以被编译器或运行时环境用来执行特定的任务。...在实际项目中,理解并熟练运用自定义注解能有效提高代码质量和可维护性。

    深入浅出Java注解(注解概述+注解的本质+反射注解信息+元注解+属性的数据类型及特别的属性:value和数组)

    `@Inherited` 元注解用于指定注解是否可以被继承。 反射注解信息 反射是 Java 中一种获取类的信息的机制。我们可以使用反射机制来获取类的注解信息。例如,我们可以使用 `getAnnotation()` 方法来获取类的注解。 ...

    Java Annotation手册

    《Java Annotation手册》 在Java编程语言中,...理解并熟练运用注解,可以提高开发效率,增强代码的可维护性和扩展性。通过自定义注解,开发者可以为特定项目或库添加定制化的元数据,进一步提升软件工程的灵活性。

Global site tag (gtag.js) - Google Analytics