注解这东西虽然在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. 读《架构探险——从零开始写Java Web框架》

    内容提要 <架构探险--从零开始写Java Web框架>首先从一个简单的 Web 应用开始,让读者学会如何使用 IDEA.Maven.Git 等开发工具搭建 Java Web 应用:接着通 ...

  2. OutputDebugString()

    坚定的 Win32 开发者可能对 OutputDebugString() API 函数比較熟悉,它能够使你的程序和调试器进行交谈.它要比创建日志文件easy,并且全部“真正的”调试器都能使用它.应用程 ...

  3. Android-Chat-Widget

    Original: https://github.com/ijarobot/Android-Chat-Widget Backup: https://github.com/eltld/Android-C ...

  4. iOS开发——语法OC篇&Block回顾

    Block回顾 这里知识简单介绍一下关于Block的语法,如果你觉得这里很简单或者想学习更深入的的使用清查看记者之前写的使用block传值和高级Block使用: http://www.cnblogs. ...

  5. iOS开发——UI篇Swift篇&UISwitch/UIStepper

    UISwitch/UIStepper override func viewDidLoad() { super.viewDidLoad() titleLabel.text = titleString / ...

  6. oc-25-id类型

    /** id:万能指针 能够指向任何OC对象. id = NSObject *, id cat = [Cat new]; [cat jump]; NSObject:是所有类的父类,基类.可以指向任何O ...

  7. java 哈夫曼编码

    //哈夫曼树类 public class HaffmanTree { //最大权值 ; int nodeNum ; //叶子结点个数 public HaffmanTree(int n) { this. ...

  8. 二进制序列化框架easypack发布啦!

    简介 easypack是基于boost.serialization的二进制序列化框架,使用极其方便. Examples 基本类型 int age = 20; std::string name = &q ...

  9. C++ atol

    函数名: atol 功 能: 把字符串转换成长整型数 用 法: long atol(const char *nptr);   简介编辑 相关函数: atof,atoi,strtod,strtol,st ...

  10. Override Inline Styles with CSS

    inline style: <div style="background: red;"> The inline styles for this div should m ...