测试java反射,用构建器创建对象,访问私有方法与字段

本文介绍了如何利用Java反射API来获取类信息、构造器、字段和方法,并详细讲解了如何访问私有成员,包括设置访问权限、创建对象、读写私有字段以及调用私有方法。示例代码展示了实际操作过程。
摘要由CSDN通过智能技术生成

首先需要获取类型类,一般获取类型类有三种方式

  1. 从类名获得:MyClass.class即可,适用于知道类名
  2. 从对象获得:myClass.getClass(),适用于有对象句柄
  3. 偷来的:Class.forName(“com.crimson.MyClass”)需要类名和包名,不常用

这里选了第一种,假设获取的对象为a。
然后是获取该类型的构造器,方法和字段。
全都依靠以get开头的各种方法。
根据返回对象不同有constructor、field、method三种,意思是构造器、字段和方法。根据访问权限不同有公开的和公开+私有,加上Declared获取的就是公开+私有。
如getDeclaredMethods获取所有方法、getMethods仅获取公开方法,getFields仅获取公开的字段。返回对象的用对应的数组装起来就可以了,在代码里第一段里有演示。如Method methods[]=a.getDeclaredMethods()。

private的可以访问前,先setAccessible(true),把访问权限强制打开,访问完记得再关闭就可以了。

获取指定名字的字段方法和构造器,字段和方法把名字作为参数,如getDeclaredMethod(“setId”),注意结尾是method没有s,因为只获取单个方法,也不需要用数组装了。直接Method m=getMethod(“myMethod”)。
对于获取指定的构造器,get方法里面填想获取构造器的参数的class,无参的就不填。
如果你想获取MyClass(int,int)的构造器,就getDeclaredConstructor(int.class,int.class)就可以了
同样的,获取的是单个构造器,注意结尾没有s。

对于已经获取到的构造器例如c,可以使用它的newInstance方法获取它制造的新对象,如c.newInstance(100,200)

对于已经获取到的字段对象,可以读取出来,使用get(对象)或者getInt()之类用于基本数据类型,还可以用set(对象,值)设值。
对于已经获取的方法,可以用invoke(对象,参数)调用该方法。具体流程参见下面代码。

代码如下

package com.crimson.master;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** 分析反射 */
public class MyReflection
{
    public MyReflection(int n)
    {
        this.a=n;
    }
    public int getA()
    {
        return a;
    }

    public void setA(int a)
    {
        this.a = a;
    }
    private void setB(int n)
    {
        this.b=n;
    }

    private int a=0;
    public int b=0;
    public static void main(String[] args)
    {
        MyReflection myReflection=new MyReflection(-1);
       Class<?> myReflectionClass=myReflection.getClass();
       //获取所有构造器并打印
        Constructor<?> constructors[]=myReflectionClass.getDeclaredConstructors();
        System.out.println(constructors);
        //获取所有方法与字段
        Method methods[]=myReflectionClass.getDeclaredMethods();
        Field fields[]=myReflectionClass.getDeclaredFields();
        //打印方法与字段名
        List<Method> mlist=new ArrayList<Method>(Arrays.asList(methods));
        mlist.stream().forEach(System.out::println);
        List<Field> mfield=new ArrayList<Field>(Arrays.asList(fields));
        mfield.stream().forEach(System.out::println);
        
        try
        {
            //测试从构造器获取对象
            Constructor<?> intConstructor=myReflectionClass.getDeclaredConstructor(int.class);
            System.out.println(intConstructor);
            MyReflection newIns=(MyReflection)intConstructor.newInstance(900);
            System.out.println(newIns.getA());
            
            //测试字段,访问private字段
            Field a=myReflectionClass.getDeclaredField("a");
            a.setAccessible(true);//开权限
            System.out.println(a.getInt(myReflection));
            a.set(myReflection,100);//反射所提供的set方法
            a.setAccessible(false);//关权限
            System.out.println(myReflection.getA());
            //测试方法
            Method seta=myReflectionClass.getDeclaredMethod("setA",int.class);
            seta.invoke(myReflection,200);//调用方法
            System.out.println(myReflection.getA());
        } catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException e)
        {
            e.printStackTrace();
        }

    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值