Java反射

目录

1.获取class对象的三种方式

2.构造方法的获取

2.1.见下面代码

 2.2.获取所有的构造方法,无论公有还是私有。

2.3.获取单个构造方法

 2.4获取构造方法的权限修饰符

 2.5获取构造方法的参数

 2.6 获取构造方法,并利用构造方法创建对象

​3.利用反射获取成员变量

 

3.1获取成员变量的记录的值

 3.2修改成员变量记录的值


1.获取class对象的三种方式

case1:Class.forName("全类名");--->源代码阶段(常用)

case2:类名.class;-----》加载阶段(编译阶段)(一般更多当作参数进行传递)

case3:对象.getClass();-----》运作阶段(已经有了这个类的对象时才可以使用)

以Student类为例:

package com.hb.relflect;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

以下代码为三种使用方式:

package com.hb.relflect;

public class MyReflect1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.第一种方式
        //全类名=包名+类名
        Class<?> aClass = Class.forName("com.hb.relflect.Student");

        //2.第二种方式
        Class<Student> studentClass = Student.class;


        //3.第三种方式
        Student student=new Student();
        Class class3 =student.getClass();

    }
}

2.构造方法的获取

2.1.见下面代码

返回public修饰的构造方法。

package com.hb.relflect;

import java.lang.reflect.Constructor;

public class MyReflect1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.获取字节码文件对象
        //全类名=包名+类名
        Class<?> aClass = Class.forName("com.hb.relflect.Student");
        //2.获取构造方法
        Constructor[] cons = aClass.getConstructors();

        for(Constructor con:cons){
            System.out.println(con);
        }

    }
}

运行结果:

 2.2.获取所有的构造方法,无论公有还是私有。

获取所有的构造方法,无论公有还是私有。

用于测试Student类

package com.hb.relflect;

public class Student {
    private String name;
    private int age;



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

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

获取所有构造方法数组:

package com.hb.relflect;

import java.lang.reflect.Constructor;

public class MyReflect1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.获取字节码文件对象
        //全类名=包名+类名
        Class<?> aClass = Class.forName("com.hb.relflect.Student");
        //2.获取构造方法
        Constructor[] cons = aClass.getDeclaredConstructors();
        for(Constructor con:cons){
            System.out.println(con);
        }


    }
}

运行结果:

 

2.3.获取单个构造方法

见下面代码及运行结果:

代码:

运行结果:

 2.4获取构造方法的权限修饰符

代码:

 运行结果:1-》public

                   2->private

                   详细见JDK api文档中的常量字段值的reflect部分

 2.5获取构造方法的参数

示例:

运行结果:

 

 2.6 获取构造方法,并利用构造方法创建对象

情况一:构造函数是public修饰时。

示例:

运行结果:

 情况二:构造函数为私有(private)

 相关代码:

Student类中的构造函数

 利用该构造函数创建对象:

运行结果:

为什么会报错?

注意:

 aClass.getDeclaredConstructor()方法只是提供一个可读功能,并未实际开放权限。

要想利用私有构造方法创建对象,应该当开放权限。

所以,代码应作如下改动:(下面这种方式也叫暴力反射

运行结果:

 3.利用反射获取成员变量

这个和获取构造函数的规律相似。这里不做详细的解释

 情况一:获取所有的public(公共)修饰的成员变量。

情况二: 获取所有的成员变量

 

情况三: 获取单个的成员变量

公有的成员变量可以用如下的方法进行获取,但是私有的采用如下操作会报错,见下图:

此时,应当调用getDeclaredField()方法进行获取。

 

 

3.1获取成员变量的记录的值

这里注意,age为私有成员变量。

 3.2修改成员变量记录的值

 4.利用反射获取成员方法

 以Student类为例:

package com.hb.relflect;

public class Student {
    private String name;
    private int age;



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

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void sleep(){
        System.out.println("睡觉");
    }
    private void eat(String sth){
        System.out.println("在吃"+sth);
    }

}

 4.1获取所有public修饰的方法(不包括构造函数)

运行结果:(没有eat()函数)

 

 

4.2 获取所有成员方法(不能获取父类的,但能获取本类中的私有方法)

 运行结果:

 4.4获取单个成员方法(包括private)

 4.5方法的运行(利用invoke(),详见动态代理)

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值