注解这东西虽然在jdk1.5就加进来了,但他的存在还是因为使用Afinal框架的view注入才知道的。一直觉得注入特神奇,加了一句就可以把对应view生成了。

下面我们来认识一下注解这个东西

一、注解相关知识

注解相当于一种标记,在javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

1、元注解:作用是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明

@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

ElementType参数有:

1)CONSTRUCTOR:用于描述构造器

2)FIELD:用于描述域

3)LOCAL_VARIABLE:用于描述局部变量
4)METHOD:用于描述方法

5)PACKAGE:用于描述包

6)PARAMETER:用于描述参数

7)TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention:用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
RetentionPoicy参数有:

1.SOURCE:在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)

3.RUNTIME:在运行时有效(即运行时保留)

@Documented 表明这个注解被javadoc工具记录,默认是不被javadoc注解的. 即声明注解@Documented,则注解类型信息会被生成在文档中

@Inherited指明被注解的类会自动继承,即:注解类中的所有属性与方法会被子类继承

二、自定义注解

语法:public @interface 注解名 {定义体}

注解方法参数要求: 
1)只能用public或默认(default)这两个访问权修饰
2)参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.

3)如果只有一个参数成员,最好把参数名称设为"value"

4)注解元素必须有确定的值。可以在定义注解的默认值中指定,或在使用注解时指定。如:String onClick() default "";

代码如下:

定义注解

 @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FindViewByIdAnnotation { int id() default 0;
String onClick() default ""; }

使用注解

 @FindContentViewAnnotation(R.layout.activity_annotation)
public class AnnotationActivity extends Activity { @FindViewByIdAnnotation(id = R.id.tvShow, onClick = "onClickShow")
private TextView tvShow; @FindViewByIdAnnotation(id = R.id.tvHello, onClick = "onClickHello")
private TextView tvHello; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FindViewUtil.initView(this);
} public void onClickShow() {
Toast.makeText(getApplicationContext(), "show Mr-Mo", Toast.LENGTH_SHORT).show();
}
public void onClickHello() {
Toast.makeText(getApplicationContext(), "hello Mr-Mo", Toast.LENGTH_SHORT).show();
}
}

三、注解处理器

注解如果不写注解处理器基本相当于注释。所以一般都会写一个注解处理器。FindViewUtil:

 public class FindViewUtil {

     private FindViewUtil() {
} public static void initView(Object object) {
initContentView(object);
initComponentView(object);
} /**
* 初始化setContentView资源布局
*
* @param object
*/
private static void initContentView(Object object) {
Class clazz = object.getClass();
FindContentViewAnnotation contentView = (FindContentViewAnnotation) clazz.getAnnotation(FindContentViewAnnotation.class);
if (contentView != null) {
try {
int resId = contentView.value();
// activity.setContentView(resId);
Method setContentViewMethod = clazz.getMethod("setContentView", int.class);
setContentViewMethod.invoke(object, resId); } catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 初始化控件
*
* @param object
*/
private static void initComponentView(final Object object) {
try {
final Class clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
FindViewByIdAnnotation viewByIdAnnotation = field.getAnnotation(FindViewByIdAnnotation.class);
if (viewByIdAnnotation != null) {
int resId = viewByIdAnnotation.id();
final String onClick = viewByIdAnnotation.onClick();
Object view;
if (object instanceof Fragment) {
Method getViewMethod = clazz.getMethod("getView");
View rootView = (View) getViewMethod.invoke(object);
view = rootView.findViewById(resId);
} else {
Method findViewByIdMethod = clazz.getMethod("findViewById", int.class);
view = findViewByIdMethod.invoke(object, resId);
} field.setAccessible(true);
field.set(object, view); if (onClick != null && onClick.trim().length() > 0) {
Object objectField = field.get(object);
if (objectField instanceof View) {
final Method onClickMethod = clazz.getMethod(onClick);
View viewItem = (View) objectField;
viewItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
onClickMethod.setAccessible(true);
onClickMethod.invoke(object);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} }

到此就是自定义注解的全部步骤,以上代码可以完成view注入功能。

本文部分知识总结自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

代码下载地址:https://github.com/MrxMo/IOCView

Java注解(自定义注解、view注入)的更多相关文章

  1. Java实现自定义注解开发

    Java实现自定义注解开发 一直都对注解开发挺好奇的,最近终于有时间自己实践了一把,记录一下 万一后期会用到呢 哈哈哈 首先我们了解一下自定义注解的标准示例,注解类使用 @interface 关键字修 ...

  2. java/springboot自定义注解实现AOP

    java注解 即是注释了,百度解释:也叫元数据.一种代码级别的说明. 个人理解:就是内容可以被代码理解的注释,一般是一个类. 元数据 也叫元注解,是放在被定义的一个注解类的前面 ,是对注解一种限制. ...

  3. Java中自定义注解类,并加以运用

    在Java框架中,经常会使用注解,而且还可以省很多事,来了解下自定义注解. 注解是一种能被添加到java代码中的元数据,类.方法.变量.参数和包都可以用注解来修饰.注解对于它所修饰的代码并没有直接的影 ...

  4. Java Annotation自定义注解详解

    在开发过程中总能用到注解,但是从来没有自己定义过注解.最近赋闲在家,研究整理了一番,力求知其然知其所以然. 本文会尝试描述什么是注解,以及通过一个Demo来说明如何在程序中自定义注解.Demo没有实际 ...

  5. Java利用自定义注解、反射实现简单BaseDao

    在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句. 这是整体的目录结构,本来是为复习注解建立的项目^.^ 好的,首先 ...

  6. Java基于自定义注解的面向切面的实现

    目的:实现在任何想要切的地方添加一个注解就能实现面向切面编程 自定义注解类 @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retentio ...

  7. [转] Java @interface 自定义注解

    [From] http://blog.csdn.net/afterlife_qiye/article/details/53748973 1. 注解的好处 注解可以替代配置文件完成对某些功能的描述,减少 ...

  8. java中自定义注解的应用

    要想深刻的理解注解,我们必须能实现自己的注解,然后应用自己的注解去实现特定的业务,使用注解可以更优雅的做到某些事情. 有这样一个场景,在需要文件导出时,我们需要将一个model中的一些重要字段导出到c ...

  9. Java如何自定义注解

    本文主要是记录所学,以供后续参考.注解是Java 1.5引入的,Java自定义注解是通过运行时靠反射获取注解,注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定 ...

  10. java 注解 + 自定义注解的使用

    java中元注解有四个: @Retention @Target @Document @Inherited:  @Retention:注解的保留位置 @Retention(RetentionPolicy ...

随机推荐

  1. Python 基础语法

    Python 基础语法 Python语言与Perl,C和Java等语言有许多相似之处.但是,也存在一些差异. 第一个Python程序 E:\Python>python Python 3.3.5 ...

  2. 从零开始学android开发-adt-bundle-eclipse下的修改android app名称

    eclipse中,打开项目根目录中的AndoirManifest.xml文件,找到如下内容 <application android:allowBackup="true" a ...

  3. BZOJ 1084: [SCOI2005]最大子矩阵 DP

    1084: [SCOI2005]最大子矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n* ...

  4. UVALive 4223 Trucking 二分+spfa

    Trucking 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8& ...

  5. 一步步学Mybatis-搭建最简单的开发环境-开篇(1)

    最近抽空学习了Mybatis这个框架,在学习的过程中也找了很多的文章,个人感觉官网上的东西太多太杂,不适合许多希望一步步快速上手的朋友们,当然觉得查阅问题的时候可以直接通过官网找还比较快或者是Stac ...

  6. grep经常使用使用方法

    grep简单介绍 正如linux的man文件里所描写叙述的那样: grep searches the named input FILEs (or standard input if no files ...

  7. Eclipse中SVN的安装步骤(两种)和用法

    一.给安装EclipseSVN,最常见的有两种方式:手动方式和使用安装向导方式.详细过程例如以下: 方式一:手动安装 1.从官网下载site-1.6.9.zip文件,网址是:subclipse.tig ...

  8. 将表中数据生成SQL语句

    在开发过程中,经常需要我们对表中的数据进行转移,如果在同台机器,可以使用SQL自带的导入数据,但是如果想让所有的数据生成可执行的SQL语句,它的移植性最强了.首先要设计一个存储过程.具体如下: CRE ...

  9. 除去字符串中不相临的重复的字符 aabcad 得 aabcd

    假设有一个字符串aabcad,请编写一段程序,去掉字符串中不相邻的重复字符.即上述字串处理之后结果是为:aabcd; 分析,重点考查 char 与int 的隐式转换.程序如下: static void ...

  10. PHP Fuzzing行动——源码审计

    目录: Section 1: 20种PHP源码快速审计方式  Section 2: PHP源码审计自动化( PHP Fuzzer )  风险级别: ■ Low ■ Medium ■ High   在开 ...