Java 反射

作者: 久伴我还是酒伴我 | 来源:发表于2020-05-22 13:37 被阅读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 反射很多,只介绍到常用的获取变量 获取构造获取方法,这几个目前够用了,后续再慢慢补充

相关文章

  • 博客地址

    java注解-01、java注解-02、Git面试资源java反射-01、java反射-02、java反射-03为...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • Java 反射机制

    Java 反射机制 什么是反射 Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”。 ...

  • 一探究竟:Java反射效率低的原因到底在哪?

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • 面试官说:大家都说 Java 反射效率低,你知道原因在哪里么

    预备知识 了解 Java 反射基本用法 看完本文可以达到什么程度 了解 Java 反射原理及 Java 反射效率低...

  • Java面试题之JavaSE高级

    一、Java中的反射 1.说说你对Java中反射的理解 java中的反射首先是能够获取到Java...

网友评论

    本文标题:Java 反射

    本文链接:https://www.haomeiwen.com/subject/edkxahtx.html