反射的原理

1.什么是反射?  框架设计的灵魂

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

反射:  运行时把类中的成员抽取出来为其他类的过程叫做反射

2.java代码从编译到运行经历了几个阶段

经历了3个阶段,

 3.如何获得反射类Class.

①.  Class.forName("类的位置")

②.  通过类名来获取  ;类.class

③.  对象

public class Test1 {
    public static void main(String[] args) throws Exception{
        //获取Class类的方式
        //1.通过全类名字符串来获取
        Class<?> aClass = Class.forName("com.wpl.demo1.student");
        //2.通过类名来获取
        Class<student> aClass1 = student.class;
        //3.对象
        student s = new student();
        Class<? extends student> aClass2 = s.getClass();
        System.out.println(aClass==aClass1);
        System.out.println(aClass==aClass2);
        System.out.println(aClass1==aClass2);
       //总结: 无论用什么样的方式得到反射类  反射类对象只有一个
    }
}
class  T extends student{
    private String sex;

}
class  student{
    private String name;
    private int age;

    public student() {
    }

    public void show(){
        System.out.println("无参方法");
    }
    public void sun(String name,int age){
        System.out.println(name+"是有参方法"+age);
    }
    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

4.如何通过反射类获取对应的反射类对象

public class Test2 {
    public static void main(String[] args) throws Exception{
        //获取反射类
        Class<student> aClass =student.class;
        //获取反射类对象
        student s= aClass.newInstance();
        System.out.println(s);
    }

}
class  T extends com.wpl.demo2.student {
    private String sex;

}
class  student{
    private String name;
    private int age;

    public student() {
    }

    public void show(){
        System.out.println("无参方法");
    }
    public void sun(String name,int age){
        System.out.println(name+"是有参方法"+age);
    }
    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

5.获取Field类的方式

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

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

public class Test2 {
    public static void main(String[] args) throws Exception{
        //获取反射类
        Class<student> aClass =student.class;
        //获取反射类对象
       Object o= aClass.newInstance();

        /**
         * 获取Field类的方式
         *
         * Field类  在java虚拟机中抽取类的属性 放入Field类中
         *
         * getDeclaredField(String name) :获取本类中指定属性名的Field对象。
         * getDeclaredFields() :获取本类中所有的属性对象
         *
         * getField(String name) :获取指定public修饰的属性名的Field对象。【包含父类的属性】
         * getFields() :获取所有public修饰的属性对象【包含父类的属性】
         */
        //获取本类中指定属性名的Field对象
       /* Field name = aClass.getDeclaredField("name");
        System.out.println(name);*/

       /* Field[] fields = aClass.getDeclaredFields();
        System.out.println(fields);*/

      /*  Field sex = aClass.getField("sex");
        System.out.println(sex);*/

      /*  Field[] fields = aClass.getFields();
        System.out.println(fields);*/

        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);// 设置私有属性的可见性,打破面向对象的封装性  不推荐使用
        name.set(o,"张三");
        System.out.println(o);
    }
}
class  T  {
    public String sex;

}
class  student extends T{
    private String name;
    public int age;

    public student() {
    }

    public void show(){
        System.out.println("无参方法");
    }
    public void sun(String name,int age){
        System.out.println(name+"是有参方法"+age);
    }
    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

6.如何获取方法类Method

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

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

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


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

        /**
         *   如何获取Method类
         *
         * getDeclaredMethod(String name, Class<?>... parameterTypes) :获取本类中指定方法名的方法对象。
         * getDeclaredMethods() :获取本类中所有的方法。
         * getMethod(String name, Class<?>... parameterTypes) :获取指定类中public修饰的方法 包含父类
         * getMethods() 获取所有的public方法
         */

        Method show = aClass.getDeclaredMethod("show");
        //  回调方法  方法名 . invoke()   括号中填写 反射类对象
        show.invoke(o);

       /* Method[] declaredMethods = aClass.getDeclaredMethods();
        System.out.println(declaredMethods);*/

        Method sub = aClass.getDeclaredMethod("sub");

      //  设置私有方法的可以见  打破了面向对象的封装性  不推荐使用
        sub.setAccessible(true);
        sub.invoke(o);
        // 获得指定public修饰的方法  包含父类
        Method sun = aClass.getMethod("sun", String.class, int.class);
        Object invoke = sun.invoke(o, "瑶瑶", 12);

    }
}
class  T  {
    public String sex;

}
class  student extends T {
    private String name;
    public int age;

    public student() {
    }

    public void show(){
        System.out.println("无参方法");
    }
    public void sun(String name,int age){
        System.out.println(name+"是有参方法"+age);
    }
    private void sub(){
        System.out.println("私有的无参构造");
    }
    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

7.如何获取构造类Constructor

getConstructor(类<?>... parameterTypes)
getConstructors()
该类Constructor中具有的方法:如果类中没有无参构造函数时。
newInstance

public class Test4 {
    public static void main(String[] args) throws Exception{
        //获取反射类
        Class<student> aClass = student.class;
        //获取反射类对象
        student s = aClass.newInstance();
        /**
         * getConstructor(类<?>... parameterTypes)
         * getConstructors()
         * 该类Constructor中具有的方法:如果类中没有无参构造函数时。
         * newInstance
         */
        Constructor<student> constructor = aClass.getConstructor();

        System.out.println(constructor);
        //当获取有参构造时 把参数的数据类型.class  填写在括号中
        Constructor<student> constructor1 = aClass.getConstructor(String.class);
        // 用 newInstance方法 把属性值填写进去
        student newInstance = constructor1.newInstance("张三");
        System.out.println(newInstance);
    }
}
class  T  {
    public String sex;

}
class  student extends T {
    private String name;
    public int age;

    public student() {
    }

    public student(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("无参方法");
    }
    public void sun(String name,int age){
        System.out.println(name+"是有参方法"+age);
    }
    private void sub(){
        System.out.println("私有的无参构造");
    }
    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

8. 获取注解类对象Annotation


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


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


        System.out.println("获取方法上的注解对象");
        Method method = aClass.getMethod("hello");
        RequestMapping annotation1 = method.getAnnotation(RequestMapping.class);
        System.out.println(annotation1);
        System.out.println(annotation1.value());
    }
}

@Service(value = "wpl")
class Doctor{
    @JsonProperty(value = "wpl",required = true)//value  required都是注解的属性
    private String name;
    @RequestMapping(value = {"hello2","hahaha","hehe"})
    public void hello(){
        System.out.println("hello");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值