栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

通过反射访问不可见的类

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

通过反射访问不可见的类

嵌套类 -在其他类(包括静态和非静态类)中定义的类
内部类 -非静态嵌套类(内部类的实例需要外部类的实例存在)

非嵌套(顶级)类

根据您的问题,我们知道您要访问的构造函数不是公共的。因此您的班级可能看起来像这样(

A
班级与我们的课程有所不同)

package package1;public class A {    A(){        System.out.println("this is non-public constructor");    }}

要创建此类的实例,我们需要进入要调用的构造函数并使之可访问。完成后,我们可以

Constructor#newInstance(arguments)
用来创建实例。

Class<?> c = Class.forName("package1.A");//full package name --------^^^^^^^^^^//or simpler without Class.forName://Class<package1.A> c = package1.A.class;//In our case we need to useConstructor<?> constructor = c.getDeclaredConstructor();//note: getConstructor() can return only public constructors//so we needed to search for any Declared constructor//now we need to make this constructor accessibleconstructor.setAccessible(true);//ABRACADABRA!Object o = constructor.newInstance();

嵌套类和内部类

如果要访问嵌套(静态和非静态)类,则

Class.forName
需要使用语法:

Class<?> clazz = Class.forName("package1.Outer$Nested");

Outer$Nested
Nested
该类是在
Outer
类内声明的。嵌套类与方法非常相似,它们可以访问其外部类的所有成员(包括私有成员)。

但是我们需要记住,内部类的实例要存在就需要其外部类的实例。通常,我们通过以下方式创建它们:

Outer outer = new Outer();Outer.Inner inner = outer.new Inner();

因此,如您所见,内部类的每个实例都具有有关其外部类的一些信息(对该外部实例的引用存储在

this$0
字段中,

因此,在创建

Inner
类实例时,
Constructor#newInstance()
您需要将第一个参数引用传递给
Outer
类实例(以模拟
outer.newInner()
行为)。

这是一个例子。

包装1

package package1;public class Outer {    class Inner{        Inner(){ System.out.println("non-public constructor of inner class");        }    }}

包装2

package package2;import package1.Outer;import java.lang.reflect.Constructor;public class Test {    public static void main(String[] args) throws Exception {        Outer outerObject = new Outer();        Class<?> innerClazz = Class.forName("package1.Outer$Inner");        // constructor of inner class as first argument need instance of        // Outer class, so we need to select such constructor        Constructor<?> constructor = innerClazz.getDeclaredConstructor(Outer.class);        //we need to make constructor accessible         constructor.setAccessible(true);        //and pass instance of Outer class as first argument        Object o = constructor.newInstance(outerObject);        System.out.println("we created object of class: "+o.getClass().getName());    }}

静态嵌套类

静态嵌套类的实例不需要Outer类的实例(因为它们是静态的)。因此,在他们的情况下,我们不需要使用

Outer.class
第一个参数作为构造函数。而且我们不需要将外部类的实例作为第一个参数传递。换句话说,代码将与非嵌套(顶级)类的代码相同(也许除了您需要在中添加
$Nested
语法的事实以外
Class.forName()
)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/452909.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号