前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >注解反射动态代理的简单学习

注解反射动态代理的简单学习

作者头像
用户7043603
发布2022-02-25 23:24:08
3170
发布2022-02-25 23:24:08
举报
文章被收录于专栏:用户7043603的专栏

一.注解

java中注解默认实现annotation接口,一般我们自定义注解的时候主要使用的是两个元注解(其他两个@Documented 与 @Inherited基本没怎么使用过)看下面

1.@Target

主要限制可以应用注解的java元素类型 ElementType.ANNOTATION_TYPE 可以应用于注解类型。 ElementType.CONSTRUCTOR 可以应用于构造函数。 ElementType.FIELD 可以应用于字段或属性。 ElementType.LOCAL_VARIABLE 可以应用于局部变量。 ElementType.METHOD 可以应用于方法级注解。 ElementType.PACKAGE 可以应用于包声明。 ElementType.PARAMETER 可以应用于方法的参数。 ElementType.TYPE 可以应用于类的任何元素。

2.@Retention

RetentionPolicy.CLASS RetentionPolicy.SOURCE RetentionPolicy.RUNTIME

RetentionPolicy.CLASS

仅仅保留在源码中,被编译器忽略,主要应用场景是apt技术,在编译期能够获取注解与注解声明的类包括类中所有成员信息,一般用于生成额外的辅助类。还有语法检查,类似@IntDef这种

RetentionPolicy.SOURCE

会被编译器保留,但是会被jvm忽略,用处主要是用在字节码增强技术,在编译出Class后,通过修改Class数据以实现修改代码逻辑目的。对于是否需要修改的区分或者修改为不同逻辑的判断可以使用注解。

RetentionPolicy.RUNTIME

用的比较多,主要是通过反射技术动态获取注解元素

简单应用

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface lengthTest {
    int max() default 0;
    int min() default  0;
    String dec() default "";
}

public class AnnLoginModel {

    private int age;

    @lengthTest(max = 10,min = 6,dec = "kkk")
    private String desc;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    
}

 public static void vaild(Object o) throws Exception{
        Class<?> ls = o.getClass();
        Field[] fields = ls.getDeclaredFields();
        for (Field field:fields) {
            lengthTest lengthTest =  field.getAnnotation(lengthTest.class);
            if(lengthTest!=null){
                if(field.getGenericType().toString().equals("class java.lang.String")){
                    field.setAccessible(true);
                    String i = (String) field.get(o);
                    if(i.length()>lengthTest.min()&&i.length()< lengthTest.max()){
                        System.out.print("没超过");
                    }else{
                        System.out.print("超过");
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        AnnLoginModel annLoginModel = new AnnLoginModel();
        annLoginModel.setAge(2);
        annLoginModel.setDesc("傻子");
        vaild(annLoginModel);
    }

这是注解加反射进行参数校验的简单例子

二.反射

反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和 方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。是Java被视为动态语言的关键。

代码语言:javascript
复制
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
    int value();
}

activity中

 @ViewInject(R.id.bt)
    Button bt;

    @ViewInject(R.id.tv)
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_annotation);
        MyViewInject.ViewInject(this);

    }

    public static void ViewInject(Activity activity) {
        Class<? extends Activity> ls = activity.getClass();
        for (Field field : ls.getDeclaredFields()) {
            ViewInject an = field.getAnnotation(ViewInject.class);//判断是否是viewinject注解
            if (an != null) {
                try {
                    field.setAccessible(true);//设置访问权限,应许操作private的属性
                    Method method = ls.getDeclaredMethod("findViewById", int.class);//拿取activity的findviewbyid方法,当然你也可以直接使用ls.findviewbyid
                    View view = (View) method.invoke(activity, an.value());//method(ac,an.value)第一个参数在哪个对象上设置调用,第二个参数方法的参数
                    field.set(activity, view);//反射字段属性赋值
                } catch (Exception e) {

                }
            }
        }

简单例子

1.获取class

一般可以通过类名,对象获取

2.创建实例

可以通过class对象的newinstance,或者构造方法constructor.newInstance 其他方法懒的介绍有点多

3.反射的缺点

Method#invoke 需要进行自动拆装箱 反射需要按照名检索方法和参数,需要检查方法可见性参数一致性,编译器无法对动态调用的代码做优化,比如内联

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.注解
    • 1.@Target
      • 2.@Retention
        • 简单应用
        • 二.反射
          • 1.获取class
            • 2.创建实例
              • 3.反射的缺点
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档