反射:
目的:可以帮助开发者更快更方便的封装框架实现扩展功能;
反射是动态的获取java的元数据信息,也就是编译后的class文件。

反射的用途:

1.通过反射机制访问java对象的属性,方法,构造方法等
2.JDBC加载驱动连接 class.forname
Class.forName(“com.mysql.jdbc.Driver”); // 动态加载mysql驱动
3.Spring容器框架IOC实例化对象

4.自定义注解生效(反射+Aop)
5.第三方核心的框架 mybatis orm

反射的优缺点:

1、优点:可以帮助开发者更快更方便的封装框架实现扩展功能。
2、缺点:
(1)反射会消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

反射的使用

1、利用反射创建对象的方式

package com.dbgs.blct.test;

import com.dbgs.blct.test.entity.User;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/** 获取class的三种方法 */
public class Test {
  public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    //创建方法1
    Class<User> user1 = User.class;
    //创建方法2
    Class<?> user2 = Class.forName("com.dbgs.blct.test.entity.User");
    System.out.println(user1==user2);
    //创建方法3,直接new
    User user4 = new User();
    Class userClass4 = user4.getClass();
  }
}

实体

package com.dbgs.blct.test.entity;

public class User {

    private String name;

    private int age;

    public String pubUser;

    public User() {
    System.out.println("无参构造函数");
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getPubUser() {
        return pubUser;
    }

    public void setPubUser(String pubUser) {
        this.pubUser = pubUser;
    }

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

2、反射常用的API

import com.dbgs.blct.test.entity.User;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test01 {
  public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
      //创建对象
      Class<?> user2 = Class.forName("com.dbgs.blct.test.entity.User");
      //获取用public修饰的字段
      Field[] fields = user2.getFields();
      for (Field field : fields) {
          System.out.println(field);
      }
      //获取所有的字段
      Field[] fieldsAll = user2.getDeclaredFields();
      for (Field field : fieldsAll) {
          System.out.println(field);
      }
     //默认构造无参构造函数
      User user = (User) user2.newInstance();
      //构建有参的构造方法,根据属性传入参数
      Constructor<User> constructor = (Constructor<User>) user2.getConstructor(String.class, int.class);
      User user3 = constructor.newInstance("name", 1);
      System.out.println(user3);
      //反射调用公共方法,括号里是公共方法名称
      Method yws = user2.getDeclaredMethod("yws");
      yws.invoke(user);

      //反射调用私有方法,括号里是私有方法名称
      Method ywsprivate = user2.getDeclaredMethod("ywsprivate");
      //赋予访问权限
      ywsprivate.setAccessible(true);
      ywsprivate.invoke(user);
      //反射调用有参数有返回值的方法,括号里是方法名称,和参数类型元数据
      Method ywssum = user2.getDeclaredMethod("ywssum", int.class, int.class);
      ywssum.setAccessible(true);
      //传入参数
      Object invoke = ywssum.invoke(user,1, 4);
      System.out.println("反射调用有参数有返回值的方法"+invoke);
  }
}

实体添加方法

 public void yws() {
    System.out.println("公共方法");
    }

    public void ywsprivate() {
        System.out.println("私有方法");
    }

    public int ywssum(int i,int j) {
        System.out.println("有参数有返回值");
        return i+j;
    }