反射---框架设计的灵魂

一、什么是反射?

①框架:就是一种半成品!好处:提高我们的开发效率,是我们的代码更加简洁

②反射:允许时把类中成员抽取为其他类的过程叫做反射

 二、获取反射类Class的方法

①通过类的全路径字符串来获取

Class.forName("全路径")

例子:spring框架<bean id="" class="类的全路径">----可以获取类对象---Class----------类对象

②通过类名来获取

类名.class

例子:mybatis框架  session.getMapper(StudentDao.class);-----反射类对象获取对应的类对象

③通过对象类获取

对象名.getClass();

当知道该类的对象时,可以通过对象来获取反射类

public class demo01 {
    public static void main(String[] args)throws Exception {
         //获取Class类的方式
         //(1)通过类的全类名字符串来获取。
        Class aClass = Class.forName("com.ykq.Student");
        //(2)通过类名来获取
        Class bClass = Student.class;
        //(3)对象
        Student s=new Student();
        Class cClass = s.getClass();
        //思考: 上面这些方式获取到的Class对象的地址是否一样?
        System.out.println(aClass==bClass); //==比较引用地址。
        System.out.println(aClass==cClass);
        System.out.println(bClass==cClass); //任何一个类的反射类对象只有一个。
    }
}
class Student{
     private String name;
     private int age;
     public void show(){
         System.out.println("~~~~~~~show~~~~~~~~~~~");
     }

    public Student() {
    }
}

三、通过反射类获取对应的类对象

public   static  void  main(String[]  args)throws  Exception{

        Class<Student> aClass=Student.class;//得到Student的反射类对象

        Student student=aClass.newInstance();//通过反射类得到对应的类对象

        System.out.println(student);

}

四、获取Field类的方式

getDeclaredField(String name):获取本类中指定属性名的Field对象

getDeclaredFields():获取本类中所有的属性对象

getField(String name):获取指定的public修饰的属性名的Field的对象(包含父类的属性)

getFields():获取所有public修饰的属性对象(包含父类的属性)

    public static void main(String[] args) throws Exception {
        System.out.println("===============获取指定public修饰的属性对象===========");
        Class<?> aClass = Class.forName("com.ykq.demo3.Student");
        Field nameField = aClass.getField("name"); //获取public指定的name属性对象
        System.out.println(nameField);
        Field sexField = aClass.getField("sex");
        System.out.println(sexField);
        System.out.println("==================获取本类中指定的属性对象=========================");
        Field nameField2 = aClass.getDeclaredField("name");//获取本类中的属性对象
        System.out.println(nameField2);
        Field ageField2 = aClass.getDeclaredField("age");//获取本类中的属性对象
        System.out.println(ageField2);
//        Field sexField2 = aClass.getDeclaredField("sex");//获取本类中的属性对象
//        System.out.println(sexField2);

        System.out.println("===============获取全部public修饰的属性对象=================");
        Field[] fields = aClass.getFields();
        for (Field f:fields) {
            System.out.println(f);
        }

        System.out.println("============获取本类中所有属性对象===================");
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field:declaredFields) {
            System.out.println(field);
        }

    }

  五、Field类中的一些操作有哪些?  

get(Object  obj)        返回该所表示的字段的值Field .指定的对象上

get(Object  obj,Object value)        为指定属性赋值

setAccessible(boolean)        设置属性的可见性


public class Test04 {
    public static void main(String[] args)throws Exception {
        Class<?> aClass = Class.forName("com.zd.demo4.Student");
        Object o = aClass.newInstance();
        Field nameField = aClass.getField("name");
        System.out.println(nameField.get(o));//获取属性name的值
        nameField.set(o,"张三");  //为name属性对象赋值
        System.out.println(nameField.get(o));

        Field ageField = aClass.getDeclaredField("age");
        ageField.setAccessible(true);//设置私有属性的可见性,打破面向对象的封装性
        ageField.set(o,15);//因为私有无法访问

        System.out.println(o);
    }
}
class Father{
    public String sex;
}
class Student extends Father {
    public String name;
    private int age;
    public void show(){
        System.out.println("~~~~~~~show~~~~~~~~~~~");
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Student() {
    }
}

六、获取方法类Method的方法:

getDeclaredMethod(String  name,Class<?>... paramenterTypes):获取本类中指定方法名的方法对象

getDeclaredMethods():获取本类中所有的方法

getMethod(String name,Class<?>.. paramterTypes):获取指定类中public修饰的方法  包含父类

getMethods():获取所有的public方法

public class Test05{
    public static void main(String[] args)throws Exception {
        Class<Student> aClass = Student.class;
        Student student = aClass.newInstance();

        Method show = aClass.getMethod("show");
        System.out.println(show);

        Method print = aClass.getMethod("print",Integer.class,String.class);
        System.out.println(print);

        Method fun = aClass.getDeclaredMethod("fun");
        System.out.println(fun);

        //回调该方法---执行该方法。
        show.invoke(student);//Object obj 对象名  Object... args:参数值

        fun.setAccessible(true);//调用私有方法时需要设置可见性
        fun.invoke(student);

        Object o = print.invoke(student, 25, "中国");

        Method toString = aClass.getMethod("toString");
        Object invoke = toString.invoke(student);
        System.out.println(invoke);
    }
}

class Father{
    public String sex;
    public void print(Integer age,String address){
        System.out.println("父类中print方法"+age+";address:"+address);
    }
}//

class Student extends Father {
    public String name;
    private int age;
    public void show(){
        System.out.println("~~~~~~~show~~~~~~~~~~~");
    }
    private void fun(){
        System.out.println("~~~~~~~fun~~~~~~~~~~~");
    }
    @Override
    public String toString() {
        return "Student{" +
                "sex="+sex+
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Student() {
    }
}

七、获取构造类Constructor的方式:

getConstructor(类<?>... parameterTypes)

getConstructors()

该类Constructor中具有的方法:如果类中没有无参构造函数时

newInstance

public class Test06 {
    public static void main(String[] args)throws Exception {
        Class<Teacher> aClass = Teacher.class; //只能调用无参构造函数
//        Constructor<Teacher> constructor = aClass.getConstructor();//无参构造函数对象
//        Teacher teacher = constructor.newInstance();
//        System.out.println(teacher);

        Constructor<Teacher> constructor2 = aClass.getConstructor(int.class);//获取参数类型为String类型的一参构造函数对象
        Teacher teacher = constructor2.newInstance(15);
        System.out.println(teacher);

        Constructor<Teacher> constructor = aClass.getConstructor(String.class, int.class);
        Teacher t = constructor.newInstance("李四", 18);
        System.out.println(t);
    }
}
class Teacher{
    private String name;
    private int age;

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

    public Teacher() {
        System.out.println("无参");
    }

    public Teacher(String name) {
        System.out.println("一餐");
        this.name = name;
    }
    public Teacher(int age) {
        System.out.println("一餐");
        this.age = age;
    }

    public Teacher(String name, int age) {
        System.out.println("全残");
        this.name = name;
        this.age = age;
    }
}

八、获取注解类对象Annotation

可以获取到类上的注解对象,还可以获取属性上的注解对象,获取方法上的注解对象

public class Test07 {
    public static void main(String[] args)throws Exception {
        System.out.println("获取类上的注解对象");
        Class<Doctor> aClass = Doctor.class;
        Service annotation = aClass.getAnnotation(Service.class);
        System.out.println(annotation);
        System.out.println(annotation.value());

        System.out.println("获取属性上的注解对象");
        Field nameField = aClass.getDeclaredField("name");
        JsonProperty annotation1 = nameField.getAnnotation(JsonProperty.class);
        System.out.println(annotation1.value());
        System.out.println(annotation1.required());

        System.out.println("获取方法上的注解对象");
        Method hello = aClass.getMethod("hello");
        RequestMapping annotation2 = hello.getAnnotation(RequestMapping.class);
        System.out.println(Arrays.toString(annotation2.value()));
    }
}
@Service(value = "hello")
class Doctor{
    @JsonProperty(value = "n",required = true)//value  required都是注解的属性
    private String name;
    @RequestMapping(value = {"hello2","hahaha","hehe"})
    public void hello(){
        System.out.println("hello");
    }
}

总结:

反射:运行时类中成员抽取为其他类的过程。

反射类:Class获取反射类的方式?

        1.通过全类名字符串来获取。Class.forName();

        2.类名来获取    类名.class

        3.对象名来获取    对象名.getClass();

获取属性成员变量Field     set(Object,value)     get(Object);

获取方法类对象Method   invoke(Object,args);

获取构造方法类对象   Constructor

获取注解类对象getAnnotation();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值