注解这东西虽然在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. 新建VM_Script

    在Hyper-V群集中,不需要设置VM的自启动,当宿主机意外关机重新启动后,上面的VM会自动转移到另一台主机:如果另一台主机处于关机状态,则宿主机重新启动后,其VM也会自启动(如果其VM在宿主机关机前 ...

  2. Pre-compile (pre-JIT) your assembly on the fly, or trigger JIT compilation ahead-of-time (转)

    Introduction All .NET developers know that one of the best features of the CLR is JIT-compilation: J ...

  3. LNMP环境下压力测试时的主要调试参数

    LNMP环境下压力测试时的主要调试参数: 进行HTTP的压力测试时,很多时候会遇到很小的并发数,服务器就会出现不响应,或者连接超时,一般导致的原因有如下几点: 一.Nginx主要调试参数 主模块参数: ...

  4. SGU 532. Building Foundation 暴力

    532. Building Foundation 题目连接: http://acm.sgu.ru/problem.php?contest=0&problem=532 Description A ...

  5. codeforces 377A. Puzzles 水题

    A. Puzzles Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/33 ...

  6. 在Swift中的ASCII到字符转换的问题

    我们在C++里处理字符通常是这样的 char a = 'A' // A = 65 printf("'%c' = %d", a + 1, a + 1) // 'B' = 66 这在号 ...

  7. IFormatProvider,ICustomFormatter,IFormattable总结

    IFormatProvider中 public object GetFormat(Type formatType); 该方法主要用于获取一个 ICustomFormatter接口的实例 ICustom ...

  8. ci框架学习中注意的事项

    视图: 加载视图:$this->load->view('name'); 一次可以加载多个视图,如: public function index() { $data['page_title' ...

  9. 基于jquery左侧带选项卡切换的焦点图

    今天给大家分享一款基于jquery左侧带选项卡切换的焦点图.这款焦点图左侧有短标题,单击切换并显示长标题.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class ...

  10. 项目源码--Android视频MV类网站客户端

    下载源码 技术要点: 1.视频MV类网站客户端框架 2.底部TAB功能模块 3.用户管理模块 4.结合优质动画技术,良好的用户体验 5.用户设置模块 6.sqlite数据库灵活的应用 7.源码带有非常 ...