Java 反射

反射就是对类中的成员变量、成员方法和构造方法进行编程访问。

要想使用反射,必须先获取class对象。

1、如何获取class对象呢?

Class这个类描述字节码文件的。

可通过以下3种方式获取:

①Class.forName("全类名")

②类名.class

③对象.getClass()

全类名就是包名+类名,这个不用自己写,IDEA中Copy Reference粘贴在括号里就是全类名

代码演示:

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式
        //这个是最经常使用的
        Class clazz1 = Class.forName("com.liu.Student");
        //第二种方式
        //这种一般是作为参数使用,比如作为锁
        Class clazz2 = Student.class;
        //第三种方式
        Student student = new Student();
        Class clazz3 = student.getClass();
        
    }
}

2、如何获取构造方法呢?

Java中万物皆对象,对于构造方法有Constructor类去描述。

(1)常用方法

规则:

①get表示获取

②Declared表示所有

③最后的s表示所有,复数形式

④如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

方法名说明
Constructor<?>[] getConstructors()获得public修饰所有的构造
Constructor<?>[] getDeclaredConstructors()获得类中所有的构造
Constructor<T> getConstructor(Class<?>... parameterTypes)获取指定构造,只能是public修饰的
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)获取指定构造,可以是类中所有的

Student类中有4个构造方法: 

 

下面尝试使用一下获取构造方法: 

a.第二个方法:获取类中所有的构造方法

     for (Constructor constructor : clazz1.getDeclaredConstructors()) {
            System.out.println(constructor);
        }

输出结果: 

 

b.第4种方法:获取指定的构造方法,如何指定呢?传递的是类中构造方法的形参变量的类型.class。

比如想获取类中两个参数的构造方法,参数类型分别是String和int,则在getDeclaredConstructor方法中传递的应该是String.class和int.class。代码如下:

运行结果报错,因为这个private的构造方法只能让你看到,并不能让你用,想用的话可以临时修改访问权限:con.setAccessible(true); 。

3、如何使用构造方法?

获取到了构造方法之后就可以拆分构造方法的各部分内容了,比如修饰符、名字、形参等等,也可以创建对象。

(1)获取构造方法的修饰符

        int modifiers = constructor.getModifiers();
        System.out.println(modifiers);

输出结果是以整数的形式进行返回的。 

 

这个整数有什么含义,可以查API帮助文档。 

(2)获取构造方法的名字

通过getName()方法获取。

(3)获取构造方法的形参

        for (Parameter p : constructor.getParameters()) {
            System.out.println(p);
        }

 输出结果如下:

(4)还可以使用newInstance()方法创建对象

        constructor.setAccessible(true);
        Object o = constructor.newInstance("zhangsan", 20);
        System.out.println((Student)o);

4、如何获取成员变量?

(1)常用方法

使用与获取构造方法类似。

方法名说明
Field[] getFields()获得public修饰所有的成员变量
Field[] getDeclaredFields()获得类中所有的成员变量
Field getField(String name)获取指定成员变量,只能是public修饰的
Field getDeclaredField(String name)获取指定成员变量,可以是类中所有的

对于后2个方法,需要指定具体的变量名,以字符串形式给出,代码演示如下: 

        //获得单个成员变量对象
        //如果获取的属性是不存在的,那么会报异常
        //Field field3 = clazz.getField("aaa");
        //System.out.println(field3);//NoSuchFieldException

        Field field4 = clazz.getField("gender");
        System.out.println(field4);

        System.out.println("===============================");
        //获取单个成员变量(私有)
        Field field5 = clazz.getDeclaredField("name");
        System.out.println(field5);

5、如何使用成员变量?

获取到了成员变量之后就可以拆分成员变量的各部分内容了,比如修饰符、名字、类型等等,也可以获取或者赋值。

(1)获取成员变量的修饰符

        //获取成员变量的修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

(2)获取成员变量的名字

        //获取成员变量的名字
        String s = name.getName();
        System.out.println(s);

(3)获取成员变量的类型

        //获取成员变量的类型
        Class<?> type = name.getType();
        System.out.println(type);

(4)获取成员变量的值

获取某个对象的某个成员变量的值,所以首先肯定要有一个对象,通过get(Object o)方法获取,代码如下:

        //获取成员变量的值
        Student student = new Student("zhangsan");
        Object o = name.get(student);
        System.out.println((String)o);

(5)给成员变量赋值

可以看到set方法有2个形参,分别是obj和value,要指定将哪个对象的name字段修改为何值。 

        //给成员变量赋值
        name.set(student,"liu");
        Object o1 = name.get(student);
        System.out.println((String)o1);

运行结果如下:

 

6、如何获取成员方法?

(1)常用方法

方法名说明
Method[] getMethods()获得public修饰所有的成员方法
Method[] getDeclaredMethods()获得类中所有的成员方法
Method getMethod(String name, Class<?>... parameterTypes)获取指定成员方法,只能是public修饰的
Method getDeclaredMethod(String name, Class<?>... parameterTypes)获取指定成员方法,可以是类中所有的

关于方法1和2有一点细节需要注意。

getMethods()方法会返回父类中的public方法。

而getDeclaredMethods()方法只会返回子类中的所有方法,不涉及到父类。

方法3获取指定的成员方法,指定的有方法名,还有方法中形参类型.class,如果没有参数就不写。

7、如何使用成员方法?

获取修饰符,名字,形参就不细说了,和构造方法的步骤差不多,重要的是invoke方法。

Object invoke(Object obj, Object... args) :运行方法

参数一:用obj对象调用该方法

参数二:调用方法的传递的参数(如果没有就不写)

返回值:方法的返回值(如果没有就不写)

代码:

        Student student = new Student(20);
        Object o = setAge.invoke(student, 30);
        System.out.println((String) o);

setAge方法: 

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值