注解这东西虽然在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. 【转】REST on Rails指南

    REST on Rails指南1:理解资源 这是来自http://www.softiesonrails.com的REST简明指南. PART I 在理解REST on Rails之前,有必要先思考一下 ...

  2. CloudStack的VO在调用setRemoved方法抛异常的原因

    今天在开发中发现一个问题,本来想对一个VO对象的removed值赋值,然后去update一下这条记录,一个最简单的set方法,但是在调用时直接抛异常了. 1: public void setRemov ...

  3. NGINX源代码剖析 之 CPU绑定(CPU亲和性)

    作者:邹祁峰 邮箱:Qifeng.zou.job@gmail.com 博客:http://blog.csdn.net/qifengzou 日期:2014.06.12 18:44 转载请注明来自&quo ...

  4. [MEAN Stack] First API -- 1. with Node.js, Express and MongoDB

    Learn how to import data into your MongoDB and then use Express to serve a simple Node.js API. Impor ...

  5. [Express] Level 2: Middleware -- 2

    Logging Middleware Help finish the following middleware code in the logger.js file: On the response  ...

  6. ubuntu在xampp下安装memcache扩展

    sudo wget http://pecl.php.net/get/memcache-2.2.1.tgz sudo tar vxzf memcache-2.2.1.tgz cd memcache-2. ...

  7. C语言输出单个汉字字符

    #include "stdio.h" #include "windows.h" int main() { ] = { "多字节字符串!OK!" ...

  8. Oracle中关于清除数据和释放表空间

    一.表的重命名 flashback table test2 to before drop rename to test3;--[to test3]将表重命名 drop table test3 purg ...

  9. css笔记 css用法:

    前端框架:AdminLTE  https://almsaeedstudio.com/themes/AdminLTE/index2.html CSS学习教程: http://www.divcss5.co ...

  10. 使用redis做pv、uv、click统计

    redis实时统计 设计思路: 1. 前端smarty插件(smarty_function_murl),将网站所有的连接生成一个urlid,后端根据获取的参数将需要的数据存入redis. 2.后端插件 ...