自定义注解
来源:互联网 发布:小非农数据公布网站 编辑:程序博客网 时间:2024/06/05 20:40
前言
今天来看看自定义注解
实例一
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitColor { enum Color{ RED,BLUE,GREEN }// 方法的名称就是参数的名称,返回值类型就是参数的值类型 Color fruitColor() default Color.BLUE;}
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitName { String value() default "apple";}
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitProvider { int id() default -1; String name() default ""; String address() default "";}
public class Apple { @FruitName("Orange") private String appleName; @FruitColor(fruitColor = FruitColor.Color.GREEN) private String appleColor; @FruitProvider(id=2,name="zhangsan",address = "北京") private String appleProvider; public void setAppleName(String appleName){ this.appleName = appleName; } public String getAppleName(){ return appleName; } public void setAppleColor(String appleColor){ this.appleColor = appleColor; } public String getAppleColor(){ return appleColor; } public void setAppleProvider(String appleProvider){ this.appleProvider = appleProvider; } public String getAppleProvider(){ return appleProvider; }}
public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void click(View view) { FruitInfoUtil.getFruitInfo(Apple.class); }}
运行结果
System.out: ====水果颜色GREENSystem.out: =====水果名称OrangeSystem.out: ===水果供应商:2--zhangsan--北京
实例二
自定义ViewMapping代替setContentView,
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ViewMapping { int value();}
public class ViewUtil {// 传入的Activity private static Class<?> activityClass; public static void inject(Object obj) { activityClass = obj.getClass(); injectContentView(obj); } private static void injectContentView(Object obj){ //判断类上是否有注解 if (activityClass.isAnnotationPresent(ViewMapping.class)) { // 获取注解对象 ViewMapping viewMapping = activityClass.getAnnotation(ViewMapping.class); //布局文件的id int layoutId = viewMapping.value(); //获取方法对象,第二个参数是可变的,代表方法需要的参数类型 try { Method setContentView = activityClass.getMethod("setContentView", int.class); //执行方法,第一个参数是执行方法的对象,第二个是方法传入的参数的值 setContentView.invoke(obj,layoutId); } catch (Exception e) { e.printStackTrace(); } } }}
使用
@ViewMapping(R.layout.main)public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewUtil.inject(this); }}
实例三
自定义注解代替fintViewById
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface FindViewById { int value();}
private static void injectViewId(Object obj){// 获取所有的属性,不包括继承的 Field[] fields = activityClass.getDeclaredFields(); for (Field field:fields) {// 判断字段是否有注解 if (field.isAnnotationPresent(FindViewById.class)) { //获取注解的值 int viewId = field.getAnnotation(FindViewById.class).value(); try { Method findViewById = activityClass.getMethod("findViewById", int.class);// 获取findViewById方法的返回值 Object viewValue = findViewById.invoke(obj, viewId); if (Modifier.PUBLIC != field.getModifiers()) { //给字段赋值前,要保证字段是可访问的 field.setAccessible(true); } //为字段赋值 field.set(obj,viewValue); } catch (Exception e) { e.printStackTrace(); } } } }
实例四
自定义注解代替点击事件
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface OnClick { //因为可能有多个控件需要点击事件,所以这里的返回值就是一个int数组 int[] value();}
private static void injectClickListener(Object obj){ Method[] methods = activityClass.getMethods(); for (Method method : methods) { //如果方法上存在OnClick的注解 if (method.isAnnotationPresent(OnClick.class)) { //获取方法上的注解 OnClick onClick = method.getAnnotation(OnClick.class); int[] viewIds = onClick.value(); //代理处理类 MInvocationhandler invocationhandler = new MInvocationhandler(obj,method); Object proxyInstance = Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class<?>[]{View.OnClickListener.class}, invocationhandler); //遍历所有控件id,设置代理 for (int i : viewIds) { try { Object view = activityClass.getMethod("findViewById", int.class).invoke(obj, i); if (view != null) { Method clickListener = view.getClass().getMethod("setOnClickListener", View.OnClickListener.class); clickListener.invoke(view,proxyInstance); } } catch (Exception e) { e.printStackTrace(); } } } } } private static class MInvocationhandler implements InvocationHandler { private Object object; private Method method; public MInvocationhandler(Object object,Method method){ this.object= object; this.method = method; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.method.invoke(object,args); } }
阅读全文
0 0
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- @自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- 自定义注解
- Windows下编写shell脚本出现\r错误解决方法
- ES6
- LeetCode: 412. Fizz Buzz
- K-diff Pairs in an Array
- 博客地址
- 自定义注解
- arm-linx-参数
- linux 6 网卡名称修改
- 播放器的基本原理(播放四步法)
- 《Python
- 用两个栈实现队列
- 安卓Android开发笔记——textview 中划线,下划线
- 【R的机器学习】模型性能提升探索:R的其他神经网络包-neuralnet
- 使数据库中的<html>标签可以显示在前端