java反射介绍、使用、获取成员变量、获取成员方法执行

反射在java中是非常强大的一个技术,很多框架内部都使用到了反射。
一、反射是什么,如何理解?
反射中包含了一个“反”字,要理解“反”的意思,就要知道“正”的意思。一般情况下我们使用某个类的时候都知道这是什么类,用来做什么,如何初始化,有什么属性和方法,例如有一个User类:

public class User {

    private Long userId;
    private String userName;
    public String sex;

    public User(){
        System.out.println("User的无参构造方法执行");
    }

    public User(Long userId){
        this.userId = userId;
        System.out.println("User的userId构造方法执行");
    }
    public User(Long userId, String userName){
        this.userId = userId;
        this.userName = userName;
        System.out.println("User的userId、userName构造方法执行");
    }

    private User(String userName){
        this.userName = userName;
        System.out.println("User的userName私有构造方法执行");
    }
    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    private void showName(String userName){
        System.out.println("userName:" + userName);
    }

    public void showSex(String sex){
        System.out.println("sex:" + sex);
    }
}

我们拿到这个类就可以直接创建对象、调用方法,这种就可以理解为"正":

User user = new User();
user.setUserId(1L);
user.setUserName("张三");

而反射就相反,我们不知道要初始化的对象是什么,也不知道初始化的对象有什么属性和方法,也就无法使用new来创建对象,这个时候我们就要使用java提供的反射技术了。

二、通过反射获取对象的三种方式

  • 1、Object类的getClass方法;
  • 2、数据对象的class静态属性;
  • 3、Class类的forName()方法;
public static void main(String[] args) throws Exception{
        // 方式一获取class,Object类的getClass()方法
        User user = new User();
        Class userClass1 = user.getClass();
        System.out.println("方式一获取class:" + userClass1);

        // 方式二获取class,数据类型的class静态属性
        Class userClass2 = User.class;
        System.out.println("方式二获取class:" + userClass2);

        // 方式三获取class,Class类的forName()方法
        Class userClass3 = Class.forName("com.elevator.maintain.crm.manager.User");
        System.out.println("方式三获取class:" + userClass3);
    }

结果:

方式一获取class:class com.elevator.maintain.crm.manager.User
方式二获取class:class com.elevator.maintain.crm.manager.User
方式三获取class:class com.elevator.maintain.crm.manager.User
  • 反射就是在运行时才知道要操作的类是什么,对于任意一个类可以知道这个类的所有属性和方法,能够调用类的任意方法和属性,这种动态获取类的信息和动态调用对象方法的功能就是java的反射机制;
    反射可以将一个java类的各个部分分解成java对象,比如类的成员变量、方法、构造方法等,都可以通过反射把每个部分映射成java对象

三、使用

  • 1、通过反射获取构造方法
public static void main(String[] args) throws Exception{
        // 1、获取class对象
        Class clazz = Class.forName("com.elevator.maintain.crm.manager.User");
        // 2、获取所有共有构造方法
        System.out.println("获取所有公有构造方法-------------------");
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c : constructors){
            System.out.println(c);
        }
        // 3、获取所有构造方法
        System.out.println("获取所有构造方法(包括私有、默认等)-------------------");
        constructors = clazz.getDeclaredConstructors();
        for(Constructor c : constructors){
            System.out.println(c);
        }

        // 4、获取一个带参构造方法,并创建对象
        System.out.println("获取构造方法创建对象-------------------");
        Constructor constructor = clazz.getConstructor(Long.class);
        Object obj = constructor.newInstance(1L);
        System.out.println("获取一个带参构造方法,并创建对象obj:" + obj);

        // 5、获取一个私有带参构造方法,并创建对象
        constructor = clazz.getDeclaredConstructor(String.class);
        // 如果是私有的,需要设置这个属性才能访问,忽略修饰符,否则会提示IllegalAccessException
        constructor.setAccessible(true);
        obj = constructor.newInstance("张三");
        System.out.println("获取一个私有带参构造方法,并创建对象obj:" + obj);
    }

执行结果:

获取所有公有构造方法-------------------
public com.elevator.maintain.crm.manager.User(java.lang.Long,java.lang.String)
public com.elevator.maintain.crm.manager.User(java.lang.Long)
public com.elevator.maintain.crm.manager.User()
获取所有构造方法(包括私有、默认等)-------------------
private com.elevator.maintain.crm.manager.User(java.lang.String)
public com.elevator.maintain.crm.manager.User(java.lang.Long,java.lang.String)
public com.elevator.maintain.crm.manager.User(java.lang.Long)
public com.elevator.maintain.crm.manager.User()
获取构造方法创建对象-------------------
User的userId构造方法执行
获取一个带参构造方法,并创建对象obj:User{userId=1, userName='null'}
User的userName私有构造方法执行
获取一个私有带参构造方法,并创建对象obj:User{userId=null, userName='张三'}
  • 2、通过反射获取成员变量
public static void main(String[] args) throws Exception{
        // 1、获取class对象
        Class clazz = Class.forName("com.elevator.maintain.crm.manager.User");
        // 2、获取所有公有属性
        System.out.println("获取所有公有属性-------------------");
        Field[] fields = clazz.getFields();
        for(Field f : fields){
            System.out.println(f);
        }

        // 3、获取所有属性(包括私有等)
        System.out.println("获取所有属性(包括私有等)-------------------");
        fields = clazz.getDeclaredFields();
        for(Field f : fields){
            System.out.println(f);
        }

        // 4、获取公有属性并调用
        System.out.println("获取公有属性并调用-------------------");
        Field field = clazz.getField("sex");
        System.out.println(field);
        Object obj = clazz.getConstructor().newInstance();
        field.set(obj, "男");
        System.out.println(obj);

        // 4、获取公有属性并调用
        System.out.println("获取私有属性并调用-------------------");
        field = clazz.getDeclaredField("userName");
        System.out.println(field);
        field.setAccessible(true);
        obj = clazz.getConstructor().newInstance();
        field.set(obj, "李四");
        System.out.println(obj);
    }

执行结果:

获取所有公有属性-------------------
public java.lang.String com.elevator.maintain.crm.manager.User.sex
获取所有属性(包括私有等)-------------------
private java.lang.Long com.elevator.maintain.crm.manager.User.userId
private java.lang.String com.elevator.maintain.crm.manager.User.userName
public java.lang.String com.elevator.maintain.crm.manager.User.sex
获取公有属性并调用-------------------
public java.lang.String com.elevator.maintain.crm.manager.User.sex
User的无参构造方法执行
User{userId=null, userName='null', sex='男'}
获取私有属性并调用-------------------
private java.lang.String com.elevator.maintain.crm.manager.User.userName
User的无参构造方法执行
User{userId=null, userName='李四', sex='null'}
  • 3、通过反射获取成员方法
public static void main(String[] args) throws Exception{
        // 1、获取class对象
        Class clazz = Class.forName("com.elevator.maintain.crm.manager.User");
        // 2、获取所有公有方法(包括父类方法)
        System.out.println("获取所有公有方法(包括父类方法)-------------------");
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            System.out.println(m);
        }

        // 3、获取所有方法(包括私有)
        System.out.println("获取所有方法(包括私有)-------------------");
        methods = clazz.getDeclaredMethods();
        for(Method m : methods){
            System.out.println(m);
        }

        // 4、获取公有方法并调用
        System.out.println("获取公有方法并调用-------------------");
        Method method = clazz.getMethod("showSex", String.class);
        // 创建实例对象
        Object obj = clazz.getConstructor().newInstance();
        // 调用方法
        method.invoke(obj, "男");

        // 5、获取私有方法并调用
        System.out.println("获取私有方法并调用-------------------");
        method = clazz.getDeclaredMethod("showName", String.class);
        // 创建实例对象
        obj = clazz.getConstructor().newInstance();
        method.setAccessible(true);
        // 调用方法
        method.invoke(obj, "李四");
    }

执行结果:

获取所有公有方法(包括父类方法)-------------------
public java.lang.String com.elevator.maintain.crm.manager.User.toString()
public void com.elevator.maintain.crm.manager.User.showSex(java.lang.String)
public java.lang.Long com.elevator.maintain.crm.manager.User.getUserId()
public java.lang.String com.elevator.maintain.crm.manager.User.getSex()
public void com.elevator.maintain.crm.manager.User.setUserId(java.lang.Long)
public void com.elevator.maintain.crm.manager.User.setUserName(java.lang.String)
public void com.elevator.maintain.crm.manager.User.setSex(java.lang.String)
public java.lang.String com.elevator.maintain.crm.manager.User.getUserName()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
获取所有方法(包括私有)-------------------
public java.lang.String com.elevator.maintain.crm.manager.User.toString()
public void com.elevator.maintain.crm.manager.User.showSex(java.lang.String)
private void com.elevator.maintain.crm.manager.User.showName(java.lang.String)
public java.lang.Long com.elevator.maintain.crm.manager.User.getUserId()
public java.lang.String com.elevator.maintain.crm.manager.User.getSex()
public void com.elevator.maintain.crm.manager.User.setUserId(java.lang.Long)
public void com.elevator.maintain.crm.manager.User.setUserName(java.lang.String)
public void com.elevator.maintain.crm.manager.User.setSex(java.lang.String)
public java.lang.String com.elevator.maintain.crm.manager.User.getUserName()
获取公有方法并调用-------------------
User的无参构造方法执行
sex:男
获取私有方法并调用-------------------
User的无参构造方法执行
userName:李四

你可能感兴趣的:(java,反射,java)