设计模式基础

这里写目录标题

Java注解

  • Java注解( Annotation)注解其实就是代码里的特殊标记,它用于替代配置文件:传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。

  • 注解可以标记在包、类、属性、方法,方法参数以及局部变量上,且同一个地方可以同时标记多个注解。

内置的注解:

  • @Override:检查该方法是否是重载方法。如果发现其父类或者是其引用的接口中并没有该方法时,会报编译错误。
  • @Deprecated:标记过时方法,如果使用该方法,会报编译警告
  • @SuppressWarnings:指示编译器去忽略注解中声明的警告

以下为作用在其他注解的注解(元注解)

  • @Retention:定义了该Annotation被保留的时间长短:
  1. 某些Annotation仅出现在源代码中,而被编译器丢弃;
  2. 另一些却被编译在class文件中,注解保留在class文件中,在加载到JVM虚拟机时丢弃,这是默认行为,所以没有用Retention注解的注解,都会采用这种策略
  3. 而另一些在class被装载时将被读取,注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解

作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

取值(RetentionPoicy)有:

  1. SOURCE:在源文件中有效(即源文件保留)
  2. CLASS:在class文件中有效(即class保留)
  3. RUNTIME:在运行时有效(即运行时保留)
  • @Documented:Documented注解的作用是:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。

  • @Target:描述注解的使用范围(即:被修饰的注解可以用在什么地方)。Target注解用来说明那些被它所注解的注解类可修饰的对象范围:注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数),在定义注解类时使用了@Target 能够更加清晰的知道它能够被用来修饰哪些对象

  • @Inherited:使被它修饰的注解具有继承性(如果某个类使用了被@Inherited 修饰的注解,则其子类将自动具有该注解)。

  • @SafeVarargs:Java7开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

  • @FunctionalInterface:标识一个匿名函数或者函数式接口

  • @Repeatable:标识某注解可以在同一个声明上使用多次。

简单的元注解(修饰自己写的注解)例子:

@Documented
@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnoation {
}

反射

  1. Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

  2. Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

被操作对象People:

package zxc;

import zxv.Column;

public class People {
    @Column("用户名")//反射注解
    private String name;
    private int age;

    public People(){

    }
    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

被反射的注解:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String value();
}

进行反射:

//   类中的成员:方法,属性,构造器
    @Test
    public void reflect(){
        try {
            //class[People]---->class(运行时类)---->c[对象]
            Class <?> c=Class.forName("zxc.People");//加载到内存中


           //通过反射得到默认构造器
            Constructor con=c.getConstructor();//得到默认构造器
            People p=(People)con.newInstance();//相当于实例化
            p.setAge(12);
            System.out.println(p.getAge());
            //通过反射得到非默认构造器
            Constructor con1=c.getConstructor(String.class,int.class);//得到默认构造器
            People p1=(People) con1.newInstance("like",12);
            System.out.println(p1.getName());


            //方法反射
            Constructor con2=c.getConstructor();
            People p2=(People) con2.newInstance();
            Method m= c.getMethod("setName", String.class);//反射得到setName方法
            m.invoke(p2,"like");//p2.setName()
            Method m1= c.getMethod("getName");//反射得到getName方法
            System.out.println(m1.invoke(p2));

            //属性反射
            Constructor con3=c.getConstructor();
            People p3=(People) con3.newInstance();
            Field[] fs=c.getDeclaredFields();//显示所有字段    c.getFields()显示非私有字段
            Arrays.asList(fs).forEach(f->System.out.println(f.getName()));
            //反射字段
            Field f=c.getDeclaredField("name");//因为属性:name是私有的,所以此函数没有权限访问私有属性
            f.setAccessible(true);//给以访问权限
            f.set(p,"like");
            System.out.println(f.get(p));


          //反射数组
            Object o =Array.newInstance(String.class,5);//  String []a=new String[5];
            Array.set(o,0,"awsl");
            Array.set(o,1,"yyds");
            Array.set(o,2,"hust");
            Array.set(o,3,"comq");
            System.out.println(Array.get(o,3));


            //反射注解
            Class cq=People.class;//和Class c=Class.forName("zxc.People");一个意思
            Field fsq[]=cq.getDeclaredFields();
            for(Field fq:fsq){
                if(fq.isAnnotationPresent(Column.class)){
                    Column cl=fq.getAnnotation(Column.class);
                    if(cl.value().equals("用户名"));
                    System.out.println(cl);
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值