Java之反射

java反射是框架设计的灵魂

反射的概念:

反射就是获取类的字节码文件,可以使我们在运行状态获取任何一个类的方法和属性。对于任意一个对象,都能够调用它的任意方法和属性。

反射,获取字节码文件对象的三种方式

1.第一种方式

 /**第一种方式*/
        //创建一个对象
        Student stu=new Student();
        //获取该对象的class对象
        Class c=stu.getClass();
        //获取类名称
        System.out.println(c.getName());

2.第二种方式

        /**第二种方式*/
        Class c2=Student.class;
        //获取类名称
        System.out.println(c2.getName());

3.第三种方式

/**第三种方式*/
        Class c3=Class.forName("com.jjp.domain.Student");
        //获取类名称
        System.out.println(c3.getName());

由于第三种方式可用于配置文件中,在实际应用中,我们多用第三种方式

通过反射获取类的构造方法,方法以及属性

0.定义一个Student类
package com.jjp.domain;

public class Student {
    private String name;  //私有
    private int age;
    public String sex;   //公共
    protected String birthday;  //保护
    int height;     //高度

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    private Student(String name) {
        this.name = name;
    }

    public Student() {
    }

    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 getSex() {
        return sex;
    }

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

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
    private void eat(String food){
        System.out.println("eat..."+food);
    }
    public String sleep(String place){
        System.out.println("sleep..."+place);
        return "身体好";
    }
    public void method1(){
        System.out.println("public修饰的方法");
    }
    protected void method2(){
        System.out.println("protected修饰的方法");
    }
    void method3(){
        System.out.println("默认修饰");
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", birthday='" + birthday + '\'' +
                ", height=" + height +
                '}';
    }
}

1.获取构造方法
public static void main(String[] args)throws ClassNotFoundException,NoSuchMethodException,
            IllegalAccessError,InstantiationError{
        //加载Class对象
        Class c=Class.forName("com.jjp.domain.Student");
        System.out.println("======================获取所有公用的构造方法======================");
        Constructor[] constructors=c.getConstructors();
        for(Constructor constructor:constructors){
            System.out.println(constructor);
        }
        System.out.println("======================获取所有的构造方法======================");
        Constructor[] constructors1=c.getDeclaredConstructors();
        for(Constructor constructor:constructors1){
            System.out.println(constructor);
        }
        System.out.println("====================获取公有无参的构造方法======================");
        Constructor constructor=c.getConstructor(null);
        System.out.println(constructor);
        System.out.println("=====================获取公有有参构造方法======================");
        Constructor constructor1=c.getConstructor(String.class,Integer.class);
        System.out.println(constructor1);
        System.out.println("=====================获取私有有参构造方法=======================");
        Constructor declareConstructor1=c.getDeclaredConstructor(String.class);
        System.out.println(declareConstructor1);
    }

结果如下:

======================获取所有公用的构造方法======================
public com.jjp.domain.Student()
public com.jjp.domain.Student(java.lang.String,java.lang.Integer)
======================获取所有的构造方法======================
public com.jjp.domain.Student()
private com.jjp.domain.Student(java.lang.String)
public com.jjp.domain.Student(java.lang.String,java.lang.Integer)
====================获取公有无参的构造方法======================
public com.jjp.domain.Student()
=====================获取公有有参构造方法======================
public com.jjp.domain.Student(java.lang.String,java.lang.Integer)
=====================获取私有有参构造方法=======================
private com.jjp.domain.Student(java.lang.String)
2.获取类字段
package com.jjp.reflect;

import com.jjp.domain.Student;

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

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException
            ,NoSuchFieldError,IllegalAccessError, InstantiationError, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //加载Class对象
        Class cls=Class.forName("com.jjp.domain.Student");
        System.out.println("===获取所有公共字段==");
        Field[] fields=cls.getFields();
        for(Field field:fields){
            System.out.println(field);
        }

        System.out.println("====获取所有字段===");
        Field[] fields1=cls.getDeclaredFields();
        for(Field field:fields1){
            System.out.println(field);
        }
        System.out.println("===获取公有字段并使用====");
        //获取指定公有字段
        Field field=cls.getField("sex");
        //获取一个公有构造方法然后实例化。
        Object obj=cls.getConstructor().newInstance();
        //为属性设置值
        field.set(obj,"male");
        //测试,看设置的值是否成功
        Student stu=(Student)obj;
        System.out.println(stu.getSex());

        System.out.println("=====获取私有字段并使用=====");
        Field field1=cls.getDeclaredField("name");
        //获取构造函数,并实例化对象
        Object obj1=cls.getConstructor().newInstance();
        //暴力反射
        field1.setAccessible(true);
        //给属性设置
        field1.set(obj1,"张三");
        //测试
        Student stu1=(Student)obj1;
        System.out.println(stu1.getName());
    }

}

结果如下:

===获取所有公共字段==
public java.lang.String com.jjp.domain.Student.sex
====获取所有字段===
private java.lang.String com.jjp.domain.Student.name
private int com.jjp.domain.Student.age
public java.lang.String com.jjp.domain.Student.sex
protected java.lang.String com.jjp.domain.Student.birthday
int com.jjp.domain.Student.height
===获取公有字段并使用====
male
=====获取私有字段并使用=====
张三

注:在使用私有字段的时候一定需要进行暴力反射field1.setAccessible(true);

3.获取类中的方法
package com.jjp.reflect;

import com.jjp.domain.Student;

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

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException
            ,NoSuchFieldError,IllegalAccessError, InstantiationError, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //加载Class对象
        Class cls=Class.forName("com.jjp.domain.Student");

        System.out.println("=====获取所有的public修饰的方法======");
        Method[] methods=cls.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }
        System.out.println("=========获取所有的方法=============");
        Method[] methods1=cls.getDeclaredMethods();
        for(Method method:methods1){
            System.out.println(method);
        }
        System.out.println("==========获取私有方法(带参带返回值)并使用============");
        Method method1=cls.getDeclaredMethod("eat",String.class);
        System.out.println(method1);
        method1.setAccessible(true);
        Object obj=cls.getConstructor().newInstance();
        method1.invoke(obj,"玉米");

        System.out.println("==========获取公共方法(带参)并使用============");
        Method method2=cls.getMethod("sleep",String.class);
        System.out.println(method2);
        Object returnValue=method2.invoke(obj,"早");
        System.out.println(returnValue);
    }

}

运行结果:

=====获取所有的public修饰的方法======
public java.lang.String com.jjp.domain.Student.toString()
public java.lang.String com.jjp.domain.Student.getName()
public void com.jjp.domain.Student.setName(java.lang.String)
public java.lang.String com.jjp.domain.Student.sleep(java.lang.String)
public void com.jjp.domain.Student.method1()
public int com.jjp.domain.Student.getAge()
public void com.jjp.domain.Student.setBirthday(java.lang.String)
public java.lang.String com.jjp.domain.Student.getBirthday()
public void com.jjp.domain.Student.setAge(int)
public void com.jjp.domain.Student.setSex(java.lang.String)
public java.lang.String com.jjp.domain.Student.getSex()
public void com.jjp.domain.Student.setHeight(int)
public int com.jjp.domain.Student.getHeight()
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.jjp.domain.Student.toString()
public java.lang.String com.jjp.domain.Student.getName()
public void com.jjp.domain.Student.setName(java.lang.String)
public java.lang.String com.jjp.domain.Student.sleep(java.lang.String)
public void com.jjp.domain.Student.method1()
private void com.jjp.domain.Student.eat(java.lang.String)
protected void com.jjp.domain.Student.method2()
public int com.jjp.domain.Student.getAge()
public void com.jjp.domain.Student.setBirthday(java.lang.String)
public java.lang.String com.jjp.domain.Student.getBirthday()
public void com.jjp.domain.Student.setAge(int)
public void com.jjp.domain.Student.setSex(java.lang.String)
void com.jjp.domain.Student.method3()
public java.lang.String com.jjp.domain.Student.getSex()
public void com.jjp.domain.Student.setHeight(int)
public int com.jjp.domain.Student.getHeight()
==========获取私有方法(带参)并使用============
private void com.jjp.domain.Student.eat(java.lang.String)
eat...玉米
==========获取公共方法(带参)并使用============
public java.lang.String com.jjp.domain.Student.sleep(java.lang.String)
sleep...早
身体好

注:在获取方法时,会把类的所有继承类,Object类中的方法也打印出来。

总结

以通过反射获得Method对象为例,一般会提供四种方法

  • getMethod(parameterTypes)

  • getMethods()

  • getDeclaredMethod(parameterTypes)

  • getDeclaredMethods()。
    getMethod(parameterTypes)用来获取某个公有的方法的对象
    getMethods()获得该类所有公有的方法
    getDeclaredMethod(parameterTypes)获得该类某个方法
    getDeclaredMethods()获得该类所有方法

  • 带有Declared修饰的方法可以反射到私有的方法,

  • 没有Declared修饰的只能用来反射公有的方法。其他的Annotation、Field、Constructor也是如此。

  • 获得类相关的方法
    在这里插入图片描述

  • 获得类中属性相关的方法

在这里插入图片描述

  • 获得类中注解相关的方法
    在这里插入图片描述

  • 获得类中构造器相关的方法
    在这里插入图片描述

  • 获得类中方法相关的方法
    在这里插入图片描述

  • 类中其他重要的方法
    在这里插入图片描述

  • Field类
    在这里插入图片描述

  • Method类
    在这里插入图片描述

  • Constructor类
    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值