Java反射及示例代码

反射:将类的各个组成部分封装为其他对象,这就是反射机制

反射好处:(1)可以在程序运行过程中,操作这些对象。(2)可以解耦,提高程序的可扩展性。

获取Class对象的方式:

  • Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象。(多用于配置文件,将类名定义在配置文件中。读取文件,加载类)
  • 类名.class:通过类名的属性class获取。(多用于参数的传递)
  • 对象.getClass():getClass()方法在Object类中定义着。(多用于对象的获取字节码的方式)
package com.calvin.reflect;

/**
 * @Title ReflectDemo01
 * @Description
 * @author calvin
 * @date: 2020/2/9 9:24 PM 
 */
public class ReflectDemo01 {

    public static void main(String[] args) throws Exception {
        // 1.Class.forName("全类名")
        Class class1 = Class.forName("com.calvin.reflect.Person");
        System.out.println("class1:" + class1);
        // 2.类名.class
        Class class2 = Person.class;
        System.out.println("class2:" + class2);
        // 3.对象.getClass()
        Person p = new Person();
        Class class3 = p.getClass();
        System.out.println("class3:" + class3);
        System.out.println(class1 == class2);
        System.out.println(class2 == class3);
    }

}

其中Person类的代码如下:

package com.calvin.reflect;

import lombok.Data;
import lombok.ToString;

/**
 * @Title Person
 * @Description
 * @author calvin
 * @date: 2020/2/9 9:23 PM 
 */

@Data
@ToString // 使用lombok来自动生成get,set,toString方法
public class Person {

    private String name;

    private int age;

    public String a;

    protected String b;

    String c;

    private String d;

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

    public Person() {

    }

    private Person(String name, String c) {
        this.name = name;
        this.c = c;
    }

    public void eat() {
        System.out.println("eat...");
    }

    public void eat(String food) {
        System.out.println("eat..." + food);
    }

    private void run(String miles) {
        System.out.println("run..." + miles);
    }
}

控制台输出结果:
class1:class com.calvin.reflect.Person
class2:class com.calvin.reflect.Person
class3:class com.calvin.reflect.Person
true
true

结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

接着我们去使用class对象的功能

(1)获取成员变量

package com.calvin.reflect;

import java.lang.reflect.Field;

/**
 * @Title ReflectDemo02
 * @Description
 * @author calvin
 * @date: 2020/2/9 9:50 PM 
 */
public class ReflectDemo02 {

    public static void main(String[] args) throws Exception {
        // 0.获取Person的Class对象
        Class personClass = Person.class;
        // 1.Field[] getFields() 获取所有public修饰的成员变量
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println("field:" + field);
        }
        // 2.Field getField(String name) 获取指定名称的public修饰的成员变量
        Field a = personClass.getField("a");
				System.out.println("a:" + a);
        // 获取成员变量a的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println("value:" + value);
        // 设置a的值
        a.set(p, "张三");
        System.out.println("p:" + p);
        Object value2 = a.get(p);
        System.out.println("value2:" + value2);
        // 3.Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("declaredField:" + declaredField);
        }
        // 4.Field getDeclaredField(String name) 获取指定名称的成员变量,不考虑修饰符
        Field d = personClass.getDeclaredField("d");
				System.out.println("d:" + d);
        // 忽略访问权限修饰符的安全检查(暴力反射)
        d.setAccessible(true);
        Object value3 = d.get(p);
        System.out.println("value3:" + value3);
        d.set(p, "222");
        System.out.println("p:" + p);
        Object value4 = d.get(p);
        System.out.println("value4:" + value4);
    }

}

控制台输出:
field:public java.lang.String com.calvin.reflect.Person.a
a:public java.lang.String com.calvin.reflect.Person.a
value:null
p:Person(name=null, age=0, a=张三, b=null, c=null, d=null)
value2:张三
declaredField:private java.lang.String com.calvin.reflect.Person.name
declaredField:private int com.calvin.reflect.Person.age
declaredField:public java.lang.String com.calvin.reflect.Person.a
declaredField:protected java.lang.String com.calvin.reflect.Person.b
declaredField:java.lang.String com.calvin.reflect.Person.c
declaredField:private java.lang.String com.calvin.reflect.Person.d
d:private java.lang.String com.calvin.reflect.Person.d
value3:null
p:Person(name=null, age=0, a=张三, b=null, c=null, d=222)
value4:222

(2)获取构造方法

package com.calvin.reflect;

import java.lang.reflect.Constructor;

/**
 * @Title ReflectDemo03
 * @Description
 * @author calvin
 * @date: 2020/2/9 10:13 PM 
 */
public class ReflectDemo03 {

    public static void main(String[] args) throws Exception {
        // 0.获取Person的Class对象
        Class personClass = Person.class;
        // 1.Constructor<?>[] getConstructors() 获取所有的public构造方法
        Constructor[] constructors = personClass.getConstructors();
        for (Constructor cs : constructors) {
            System.out.println("cs:" + cs);
        }
        // 2.Constructor<T> getConstructor(类<?>... parameterTypes) 获取指定的构造方法
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        System.out.println("constructor:" + constructor);
        // 创建对象(有参)
        Object person = constructor.newInstance("张三", 23);
        System.out.println("person:" + person);
        // 创建对象(无参)
        Object person1 = personClass.newInstance();
        System.out.println("person1:" + person1);
        // 3.Constructor<?>[] getDeclaredConstructors() 获取所有的构造方法,不考虑修饰符
        Constructor[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor cs1 : declaredConstructors) {
            System.out.println("cs1:" + cs1);
        }
        // 4.Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) 获取所有的构造方法,不考虑修饰符
        Constructor constructor2 = personClass.getDeclaredConstructor(String.class, String.class);
        System.out.println("constructor2:" + constructor2);
        constructor2.setAccessible(true);
        Object person2 = constructor2.newInstance("张三", "222");
        System.out.println("person2:" + person2);

    }

}

控制台输出:
cs:public com.calvin.reflect.Person()
cs:public com.calvin.reflect.Person(java.lang.String,int)
constructor:public com.calvin.reflect.Person(java.lang.String,int)
person:Person(name=张三, age=23, a=null, b=null, c=null, d=null)
person1:Person(name=null, age=0, a=null, b=null, c=null, d=null)
cs1:private com.calvin.reflect.Person(java.lang.String,java.lang.String)
cs1:public com.calvin.reflect.Person()
cs1:public com.calvin.reflect.Person(java.lang.String,int)
constructor2:private com.calvin.reflect.Person(java.lang.String,java.lang.String)
person2:Person(name=张三, age=0, a=null, b=null, c=222, d=null)

(3)获取成员方法

package com.calvin.reflect;

import java.lang.reflect.Method;

/**
 * @Title ReflectDemo04
 * @Description
 * @author calvin
 * @date: 2020/2/9 10:44 PM 
 */
public class ReflectDemo04 {

    public static void main(String[] args) throws Exception {
        // 0.获取Person的Class对象
        Class personClass = Person.class;
        // 1.Method[] getMethods() 获取所有的public成员方法
        Method[] classMethods = personClass.getMethods();
        for (Method method : classMethods) {
            System.out.println("method:" + method);
        }
        // 2.Method getMethod(String name, 类<?>... parameterTypes) 获取指定的成员方法
        Method eatMethod1 = personClass.getMethod("eat");
        Person p = new Person();
        // 执行方法
        eatMethod1.invoke(p);
        // 方法重载
        Method eatMethod2 = personClass.getMethod("eat", String.class);
        // 执行方法
        eatMethod2.invoke(p, "饭");
        // 3.Method[] getDeclaredMethods() 获取所有的成员方法,不考虑修饰符
        Method[] classMethods2 = personClass.getMethods();
        for (Method method2 : classMethods2) {
            System.out.println("method2:" + method2);
        }
        // 4.Method getDeclaredMethod(String name, 类 < ? >...parameterTypes) 获取指定的成员方法,不考虑修饰符
        Method runMethod = personClass.getDeclaredMethod("run", String.class);
        runMethod.setAccessible(true);
        Person p1 = new Person();
        // 执行方法
        runMethod.invoke(p1, "1000米");

    }

}

控制台输出:
method:public boolean com.calvin.reflect.Person.equals(java.lang.Object)method:public java.lang.String com.calvin.reflect.Person.toString()
method:public int com.calvin.reflect.Person.hashCode()
method:public java.lang.String com.calvin.reflect.Person.getName()
method:public void com.calvin.reflect.Person.setName(java.lang.String)
method:public int com.calvin.reflect.Person.getAge()
method:public java.lang.String com.calvin.reflect.Person.getA()
method:public java.lang.String com.calvin.reflect.Person.getB()
method:public java.lang.String com.calvin.reflect.Person.getC()
method:public java.lang.String com.calvin.reflect.Person.getD()
method:public void com.calvin.reflect.Person.setAge(int)
method:public void com.calvin.reflect.Person.setA(java.lang.String)
method:public void com.calvin.reflect.Person.setB(java.lang.String)
method:public void com.calvin.reflect.Person.setC(java.lang.String)
method:public void com.calvin.reflect.Person.setD(java.lang.String)
method:public void com.calvin.reflect.Person.eat(java.lang.String)
method:public void com.calvin.reflect.Person.eat()
method:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
method:public final void java.lang.Object.wait() throws java.lang.InterruptedException
method:public final native java.lang.Class java.lang.Object.getClass()
method:public final native void java.lang.Object.notify()
method:public final native void java.lang.Object.notifyAll()
eat…
eat…饭
method2:public boolean com.calvin.reflect.Person.equals(java.lang.Object)
method2:public java.lang.String com.calvin.reflect.Person.toString()
method2:public int com.calvin.reflect.Person.hashCode()
method2:public java.lang.String com.calvin.reflect.Person.getName()
method2:public void com.calvin.reflect.Person.setName(java.lang.String)
method2:public int com.calvin.reflect.Person.getAge()
method2:public java.lang.String com.calvin.reflect.Person.getA()
method2:public java.lang.String com.calvin.reflect.Person.getB()
method2:public java.lang.String com.calvin.reflect.Person.getC()
method2:public java.lang.String com.calvin.reflect.Person.getD()
method2:public void com.calvin.reflect.Person.setAge(int)
method2:public void com.calvin.reflect.Person.setA(java.lang.String)
method2:public void com.calvin.reflect.Person.setB(java.lang.String)
method2:public void com.calvin.reflect.Person.setC(java.lang.String)
method2:public void com.calvin.reflect.Person.setD(java.lang.String)
method2:public void com.calvin.reflect.Person.eat(java.lang.String)
method2:public void com.calvin.reflect.Person.eat()
method2:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method2:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
method2:public final void java.lang.Object.wait() throws java.lang.InterruptedException
method2:public final native java.lang.Class java.lang.Object.getClass()
method2:public final native void java.lang.Object.notify()
method2:public final native void java.lang.Object.notifyAll()
run…1000米

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值