• 使用反射调用类的私有内部类的私有方法



    在进行单元测试时,我们往往需要直接访问某个类的内部类或者某个类的私有方法,此时正常的调用就无能为力了,因此我们可以使用反射进行调用。

    使用反射调用类的私有方法

    package net.mooctest;
    
    public class outClass{
        public outClass() {
    
        }
        private void testMethod1(){
            System.out.println("调用了outClass的私有方法testMethod1");
        }
        
        //带参数的方法
        private void testMethod2(int a){
            System.out.println("调用了outClass的私有方法testMethod2,传入参数为:" + a);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    实现方法

    • 获取类的Class对象
      • Class class = Class.forName("类名")
      • Class class = 类实例.getClass()
    • new一个实例
      • Object object = class.newInstance();
    • 获取私有方法
      • Method method = class.getDeclaredMethod("方法名",参数类型1.class,参数类型2.class,...);
    • 设置方法可访问
      • method.setAccessible(true);
    • 调用私有方法
      • method.invoke(类实例,参数1,参数2,...);

    实现代码

    
    import static org.junit.jupiter.api.Assertions.*;
    
    import java.lang.reflect.Method;
    
    import org.junit.jupiter.api.Test;
    
    import net.mooctest.outClass;
    
    class outClassTest {
    
    	@Test
    	final void test1() throws Exception {
    		outClass out = new outClass();
    		
    		Class class1 = out.getClass();
    		
    		Object object = class1.newInstance();
    		//获取私有方法
    		Method method = class1.getDeclaredMethod("testMethod1");
    		//设置方法可访问
    		method.setAccessible(true);
    		//调用方法
    		method.invoke(object);
    		
    		
    	}
    
    	@Test
    	final void test2() throws Exception {
    		outClass out = new outClass();
    		Class class1 = out.getClass();
    		Object object = class1.newInstance();
    		//获取有参私有方法
    		Method method = class1.getDeclaredMethod("testMethod2",int.class);
    		//设置方法可访问
    		method.setAccessible(true);
    		//调用方法
    		method.invoke(object,10);
    			
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    使用反射调用类的私有内部类的私有方法

    package net.mooctest;
    
    public class outClass{
        public outClass() {
    
        }
        private void testMethod1(){
            System.out.println("调用了outClass的私有方法testMethod1()");
        }
        
        //带参数的方法
        private void testMethod2(int a){
            System.out.println("调用了outClass的私有方法testMethod2(),传入参数为:" + a);
        }
        private class inClass{
        	public inClass() {
    			// TODO Auto-generated constructor stub
    		}
        	
        	public inClass(int a) {
    			System.out.println("调用了有参构造器 " + a);
    		}
        	private void inMethod1() {
        		System.out.println("调用了类的私有内部类的私有方法inMethod1()");
        	}
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    实现方法

    • 获取私有内部类的Class对象
      • Class class = Class.forName("外部类名$内部类名")
    • 获取私有内部类构造器,无参构造器参数只填外部类名,有参构造器为(外部类名 ,参数类名…)
      • Constructor constructor = class.getDeclaredConstructor(outClass.class,参数类型1.class,参数类型2.class,...);
    • 设置构造器可访问
      • constructor.setAccessible(true);
    • new一个外部类对象,以便产生内部类实例(outClass:外部类名)
      • outClass out = new outClass();
    • 新建一个内部类实例,参数为外部类实例,若为有参构造器,后面再添加参数
      • Object object = constructor.newInstance(外部类实例,构造器参数1.class,构造器参数2.class,...);
    • 获取私有方法
      • Method method = class.getDeclaredMethod("inMethod1");
    • 设置方法可访问
      • method.setAccessible(true);
    • 调用方法
      • method.invoke(object);

    实现代码

    package test;
    
    import static org.junit.jupiter.api.Assertions.*;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    import org.junit.jupiter.api.Test;
    
    import net.mooctest.outClass;
    
    class outClassTest {
    	@Test
    	final void test3() throws Exception {
    		
    		//设置类名,外部类名$内部类名
    		String className = "net.mooctest.outClass$inClass";
    		Class class1 = Class.forName(className);
    		//获取私有内部类构造器,无参构造器参数只填外部类名,有参构造器为(外部类名 ,参数类名...)
    		Constructor constructor = class1.getDeclaredConstructor(outClass.class);
    		
    		//设置构造器可访问
    		constructor.setAccessible(true);
    		
    		//new一个外部类对象,以便产生内部类实例
    		outClass out = new outClass();
    		//新建一个内部类实例,参数为外部类实例,若为有参构造器,后面再添加参数
    		Object object = constructor.newInstance(out);
    		//获取私有方法
    		Method method = class1.getDeclaredMethod("inMethod1");
    		//设置方法可访问
    		method.setAccessible(true);
    		//调用方法
    		method.invoke(object);
    			
    	}
    	
    	@Test
    	final void test4() throws Exception {
    		
    		//设置类名,外部类名$内部类名
    		String className = "net.mooctest.outClass$inClass";
    		Class class1 = Class.forName(className);
    		//获取私有内部类构造器,无参构造器参数只填外部类名,有参构造器为(外部类名 ,参数类名...)
    		Constructor constructor = class1.getDeclaredConstructor(outClass.class,int.class);
    		
    		//设置构造器可访问
    		constructor.setAccessible(true);
    		
    		//new一个外部类对象,以便产生内部类实例
    		outClass out = new outClass();
    		//新建一个内部类实例,参数为外部类实例,若为有参构造器,后面再添加参数
    		Object object = constructor.newInstance(out,10);
    		//获取私有方法
    		Method method = class1.getDeclaredMethod("inMethod1");
    		//设置方法可访问
    		method.setAccessible(true);
    		//调用方法
    		method.invoke(object);		
    	}
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    将主机1中的数据存到主机2的MySQL数据库中
    2023高教社杯数学建模E题思路代码 - 黄河水沙监测数据分析
    C/C++常用函数
    Aeraki Mesh正式成为CNCF沙箱项目,腾讯云携伙伴加速服务网格成熟商用
    WebRTC目录结构
    还在封装 xxxForm,xxxTable 残害你的同事?试试这个工具
    一文带你搞懂JSON和TCP/IP
    [R]第二节 练习一关于数值向量
    计算机毕业设计springboot+vue基本微信小程序的线上服装店系统-服装商城
    从字节码角度带你彻底理解i++与++i
  • 原文地址:https://blog.csdn.net/HTLYing/article/details/134094784