初见

Java 反射

2020-05-22  本文已影响0人  久伴我还是酒伴我

简介

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

当JVM把class加载到内存的时候,会同步的产生关于这个文件的Class对象,这个对象里面封装的就是类的信息,而且,不管我们new 使用多少次,我们的JVM只会为它创建一个Class对象。

我们反射的本质就是得到Class对象之后,通过调用Class中的方法反向的获取Person对象的各种信息

获取Class对象

反射的关键是要获取到对象,然后调用Class对象里面的信息来达到我们的目的,比如类的路径,方法,变量等等,下面介绍下获取Class对象的几种方式

第一种

  /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) {
        Demo demo=new Demo();
        Class demoClass = demo.getClass();
        System.out.println("get class first info"+demoClass);
    }

比如传递过来Object,可通过该方式获取对象

第二种

   /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) {
        Class demoClass = Demo.class;
        System.out.println("get class second info"+demoClass);
    }

程序性能更高,安全可靠

第三种

 /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) {
        try{
            Class demoClass = Class.forName("com.glj.webservice.demo.Demo");
            System.out.println("获取到的对象:" + demoClass);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

forName() 静态方法来获取,用的最多

反射-获取成员变量

package com.glj.webservice.demo.reflex;

import java.io.Serializable;

public class ReflexClass implements Serializable {
    public String name;

    private int age;

    String address;

    protected String count;

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCount() {
        return count;
    }

    public void setCount(String count) {
        this.count = count;
    }

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

package com.glj.webservice.demo.reflex;

import java.lang.reflect.Field;
import java.util.Arrays;

public class ReflexTest {
    /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) throws Exception {
        // 获取Class 对象 可通过上述三种方式任何一种即可
        Class perClass = ReflexClass.class;

        System.out.println("获取所有字段");
        Field[] fields = perClass.getDeclaredFields();
        Arrays.stream(fields).forEach(v -> System.out.println(v));

        System.out.println("获取所有的public 字段");
        fields = perClass.getFields();
        Arrays.stream(fields).forEach(v -> System.out.println(v));

        System.out.println("根据名字获取指定字段");
        Field f = perClass.getDeclaredField("address");
        System.out.println(f);

        // 将Class 对象进行初始化
        Object ob = perClass.getConstructor().newInstance();
        f.set(ob,"北京市朝阳区望京Soho 塔1");
        ReflexClass re = (ReflexClass)ob;
        System.out.println("获取设定的值"+re.getAddress());
    }
}

打印结果:
获取所有字段
public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
private int com.glj.webservice.demo.reflex.ReflexClass.age
java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
protected java.lang.String com.glj.webservice.demo.reflex.ReflexClass.count
获取所有的public 字段
public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
根据名字获取指定字段
java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
获取设定的值北京市朝阳区望京Soho 塔1

反射-获取构造函数并调用

package com.glj.webservice.demo.reflex;

import java.io.Serializable;

public class ReflexClass implements Serializable {
    /**
     * public
     */
    public String name;
    /**
     * 默认
     */
    String address;
    /**
     * 受保护的
     */
    protected String count;
    /**
     * 私有的
     */
    private int age;

    /**
     * 无参构造
     */
    public ReflexClass() {
        System.out.println("调用了公有、无参构造方法");
    }

    /**
     * public 字段构造
     * @param name
     */
    public ReflexClass(String name) {
        this.name = name;
        System.out.println("公共字段一个参数构造 name:" + name);
    }

    /**
     * 多个字段构造
     * @param name
     * @param address
     */
    public ReflexClass(String name, String address) {
        this.name = name;
        this.address = address;
        System.out.println("name:"+name+"address:"+ address);
    }

    /**
     * protected 构造
     * @param age
     */
    protected  ReflexClass(int age) {
        this.age = age;
        System.out.println("受保护的构造方法age = " + age);
    }

    /**
     * 私有的构造
     * @param bls
     */
    private  ReflexClass(boolean bls) {
        System.out.println("受保护的构造方法bls = " + bls);
    }


    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCount() {
        return count;
    }

    public void setCount(String count) {
        this.count = count;
    }

    @Override
    public String toString() {
        return "ReflexClass{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", count='" + count + '\'' +
                '}';
    }
}
package com.glj.webservice.demo.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Arrays;

public class ReflexTest {
    /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) throws Exception {

        Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");

        System.out.println("获取所有的公有构造");
        Constructor[] constructors = demoClass.getConstructors();
        Arrays.stream(constructors).forEach(v -> System.out.println(v));

        System.out.println("所有的构造方法(包括:私有、受保护、默认、公有)");
        constructors = demoClass.getDeclaredConstructors();
        Arrays.stream(constructors).forEach(v -> System.out.println(v));

        System.out.println("获取公有的无参构造");
        Constructor constructor = demoClass.getConstructor();
        System.out.println(constructor);

        System.out.println("根据类型获取构造");
        constructor = demoClass.getDeclaredConstructor(boolean.class);
        System.out.println(constructor);

        // 暴力访问(忽略掉修饰符)
       constructor.setAccessible(true);
       constructor.newInstance(Boolean.FALSE);

    }
}

输出结果
获取所有的公有构造
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass()
所有的构造方法(包括:私有、受保护、默认、公有)
private com.glj.webservice.demo.reflex.ReflexClass(boolean)
protected com.glj.webservice.demo.reflex.ReflexClass(int)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass()
获取公有的无参构造
public com.glj.webservice.demo.reflex.ReflexClass()
根据类型获取构造
private com.glj.webservice.demo.reflex.ReflexClass(boolean)
私有构造方法bls = false

反射-获取方法并调用

package com.glj.webservice.demo.reflex;

import java.io.Serializable;

public class ReflexClass implements Serializable {
   public void getName(){
       System.out.println("调用了共有的无参方法getName");
   }
    private void getName(String name){
        System.out.println("调用了共有的无参方法getName:"+name);
    }
    protected void getAge(int age){
        System.out.println("调用了共有的无参方法getAge:"+age);
    }
    void run(){
        System.out.println("调用了:默认的,无参的run()");
    }
    private String study(int age){
        System.out.println("调用了,私有的,并且有返回值的,int参数的study(): age = " + age);
        return "abcd";
    }

    public String getAll(int age,String name){
        System.out.println("调用了公共的并且有返回值的age"+age+"name"+name);
       return "age"+age+"name"+name;
    }
}

package com.glj.webservice.demo.reflex;


import java.lang.reflect.Method;
import java.util.Arrays;

public class ReflexTest {
    /**
     * 获取Class对象
     * @param args
     */
    public static void main(String[] args) throws Exception {

        Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");

        System.out.println("获取所有的方法(私有、公有、受保护、默认)");
        Method[] methods = demoClass.getDeclaredMethods();
        Arrays.stream(methods).forEach(v -> System.out.println(v));

        System.out.println("获取所有公有的方法");
        methods = demoClass.getMethods();
        Arrays.stream(methods).forEach(v -> System.out.println(v));

        System.out.println("根据方法名称获取的方法有参");
        Method method = demoClass.getDeclaredMethod("getName",String.class);
        System.out.println(method);

        Object ob = demoClass.getConstructor().newInstance();
        method.setAccessible(true);
        //  两个参数 一个是参数值 一个是参数类型
        method.invoke(ob,"刘德华");

    }
}

输出结果
获取所有的方法(私有、公有、受保护、默认)
void com.glj.webservice.demo.reflex.ReflexClass.run()
public void com.glj.webservice.demo.reflex.ReflexClass.getName()
private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
private java.lang.String com.glj.webservice.demo.reflex.ReflexClass.study(int)
protected void com.glj.webservice.demo.reflex.ReflexClass.getAge(int)
获取所有公有的方法
public void com.glj.webservice.demo.reflex.ReflexClass.getName()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
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()
根据方法名称获取的方法有参
private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
调用了共有的无参方法getName:刘德华

总结

Java 反射很多,只介绍到常用的获取变量 获取构造获取方法,这几个目前够用了,后续再慢慢补充

上一篇下一篇

猜你喜欢

热点阅读