注解和反射

1. 正文

1. 注解
2. 反射

2. 注解

1. 注释: 对代码加以解释。注释给程序员看。
2. 注解: 注解给程序看。
注解得种类。
  1. 预定义注解。 系统中自动得一些注解。
  2. 自定义注解。
  3. 元注解。

2.1 预定义注解。---JVM虚拟机来解析。

1. @Override: 重写得注解。符合重写得规则。
2. @Deprecated: 表示已过时。
3. @SuppressWarnings: 表示压制警告。
4. @FunctionInterface: 表示函数式接口。表示该接口中有且仅有一个抽象方法。

2.2 自定义注解---初级。

格式:

public @interface 注解名{
   //注解得属性。
}

使用自定义注解:
@注解名(属性名=属性值)
public class Test03 {
}
//自定义注解
@interface MyAnnotation{

}
//使用自定义得注解
@MyAnnotation //譬如 @RequestMapping
class Student{
    @MyAnnotation
    private String name;
    @MyAnnotation
    public void show(){

    }
}

注意: 我们在定义好注解后,并使用了该注解,但是并没有对我们得程序产生影响。要想让自定义得注解有效,必须解析注解【反射时来解析。】。

疑惑: @Override 因为JVM解析了该注解。 @Controller 因为Spring框架解析了该注解。

2.3 元注解。

元注解就是声明在注解上得注解。

 

1. @Target(value=可以取下面这些内容): 作用限制注解使用得位置。   
 /** 表示可以作用在类,接口,枚举 */    TYPE,​    
/** 属性 */    FIELD,​    
/** 普通方法上 */    METHOD,​    
/** 方法参数 */    PARAMETER,​    
/** 构造方法上 */    CONSTRUCTOR,​    
/** 局部变量 */    LOCAL_VARIABLE​2. 
@Retention:  注解什么时候生效。默认时源码 java经历了那些阶段。     
 源码阶段-->字节码阶段--->运行阶段      
/**     * 源码时生效     */    SOURCE,​    
/**     * 字节码时生效     */    CLASS,​    
/**     * 运行时生效。     * 在JVM内存中还有该注解。     */    RUNTIME    
3. @Documented 当生产API文档时该注解还存在。 
​4. @Inherited 是否运行被子类继承。

2.4 自定义注解---高级

我们刚才定义得注解中什么属性都没写。正常得注解可能会存在一些属性。如何定义注解中得属性。  

public @interface 注解名{
    数据类型 属性名() default 默认值;
}
数据类型:基本数据类型 字符串 枚举 数组[只能是上面类型得数组] 注解

 注解本身没有任何意义。只有通过解析该注解才能使其富有真正得意义。通过反射来解析得注解。

 

3. 反射---框架设计得灵魂。--ORM

框架:它是一种半成品。好处: 提高开发得效率。

反射: 类在运行时把类中得成员[方法,属性,构造方法,注解]抽取为其他类得过程叫做反射

任何一个类在JVM中都存在一个影子反射对象。

3.1 如何获取反射类---Class类。

这里提供了三种获取Class类对象的方式

1. Class.forName("类的全路径");
  场景: 比如 加载驱动时。 和<bean id="" class="全路径"/> 
  spring框架根据全类获取该类的反射类。

2. 类名.class 
   场景: 在mybatis BookDao bookDao = session.getMapper(BookDao.class);

3. 对象名.getClass();
  在指定对象名的情况下使用这种方式。
public class Test01 {
    public static void main(String[] args) throws Exception{
        //①Class.forName()
        Class<?> aClass = Class.forName("com.ykq.demo01.Student");
        //②类名.class
        Class<Student> aClass1 = Student.class;
        //③对象名.getClass();
        Student s=new Student();
        Class<?> aClass2 = s.getClass();

        //思考这三个对象的地址是否相同。 任何一个字节码在JVM中有且仅存在一个对象。(相同)
        System.out.println(aClass==aClass1);
        System.out.println(aClass==aClass2);
    }
}
class Student{
      public String name;
      public void show(){
          System.out.println("show方法");
      }
}

3.2 通过反射类获取对象的类对象。

 //1.通过反射类获取对应的类对象。
        Class<Student> aClass = Student.class;
        Student student = aClass.newInstance();
        System.out.println(student);

3.3 获取属性类对象--Field.

Field getDeclaredField(String name) 获取本类中指定名称的Field对象
Field[] getDeclaredFields()  获取本类中所有的Field对象。
Field getField(String name)  获取本类以及父类中public修饰的指定Field对象。
Field[] getFields()  获取本类以及父类中public修饰的所有属性。

 

public class Test01 {
    public static void main(String[] args) throws Exception{
        Class<Student> aClass = Student.class;
        Student student = aClass.newInstance();//通过反射获取对应的实例对象
        System.out.println(student);
        System.out.println("=================获取本类中指定的属性对象===================");
        Field name = aClass.getDeclaredField("name");
        name.set(student,"某某某"); //为指定属性赋值
        Field age = aClass.getDeclaredField("age");
        age.set(student,22);
        Field width = aClass.getDeclaredField("width");
        width.setAccessible(true); //设置允许访问私有的成员
        width.set(student,20.0);
        System.out.println(student);
        System.out.println("=================获取本类中所有的属性对象===================");
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField :declaredFields){
            System.out.println(declaredField);
        }
        System.out.println("=================获取本类以及父类中所有的public属性对象===================");
        Field[] fields = aClass.getFields();
        for (Field field:fields){
            System.out.println(field);
        }
    }
    public static void 通过反射类获取实例对象()throws Exception{
        //1.通过反射类获取对应的类对象。
        Class<Student> aClass = Student.class;
        Student student = aClass.newInstance();
        System.out.println(student);
    }
    public static void 获取反射类对象()throws Exception{
        //①Class.forName()
        Class<?> aClass = Class.forName("com.ykq.demo01.Student");
        //②类名.class
        Class<Student> aClass1 = Student.class;
        //③对象名.getClass();
        Student s=new Student();
        Class<?> aClass2 = s.getClass();

        //思考这三个对象的地址是否相同。 任何一个字节码在JVM中有且仅存在一个对象。
        System.out.println(aClass==aClass1);
        System.out.println(aClass==aClass2);
    }
}
class People{
    public Double height;
}
class Student extends People{
      public String name;
      public Integer age;
      private Double width;
      public void show(){
          System.out.println("show方法");
      }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", width=" + width +
                '}';
    }
}

3.3.1 Field类中常见的方法。

1. set(Object o,Object value);为指定对象的属性赋值。
2. setAccessible(true);设置允许操作私有属性。

3.4 获取方法类对象--Method

Method getMethod(String name, Class<?>... parameterTypes) 
   获取本类以及父类种指定方法名的public方法。
Method[] getMethods() :获取本类以及父类种所有的public方法。

Method getDeclaredMethod(String name, Class<?>... parameterTypes)
   获取本类种指定方法名的方法
Method getDeclaredMethods()
   获取本类中所有方法
public class Test02 {
    public static void main(String[] args) throws Exception{
        Class<Doctor> aClass = Doctor.class;
        System.out.println("~~~~~~~~~~~~~~~~~~~获取本类以及父类种指定名称的public方法");
        Method fun = aClass.getMethod("fun");
        System.out.println(fun);

        Method fun2 = aClass.getMethod("fun2",String.class,Integer.class);
        System.out.println(fun2);
        System.out.println("~~~~~~~~~~~~~~~~~~~获取本类以及父类种所有的public方法");
        Method[] methods = aClass.getMethods();
        for (Method m:methods){
            System.out.println(m);
        }
        System.out.println("~~~~~~~~~~~~~~~~获取本类种指定方法名的方法");
        Method fun3 = aClass.getDeclaredMethod("fun3", String.class);
        System.out.println(fun3);
    }
}
class Doctor{
     public String name;

     public void fun(){
         System.out.println("hello fun");
     }

     public void fun2(String name){
         System.out.println("hello fun2==="+name);
     }
    private void fun3(String name){
        System.out.println("hello fun2==="+name);
    }
    public void fun2(String name,Integer age){
        System.out.println("hello fun2==="+name+"==="+age);
    }
}

3.4.1 Method类种常见的方法

Object r=invoke(Object,Object...value):回调指定方法。
setAccessible(true);设置允许操作私有属性。

4. 获取注解类对象---Annotation.

 


Annotation getAnnotation(String name, Class<?>... parameterTypes) 
   获取本类以及父类中注解。
Annotation[] getAnnotations() :获取本类以及父类种所有注解。

Annotation getDeclaredgetAnnotation(String name, Class<?>... parameterTypes)
   获取本类种指定注解
Annotation getDeclaredAnnotations()
   获取本类中所有注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值