如何用反射机制访问继承自私有类的方法,最好用java 实现。

如何用反射机制访问继承自私有类的方法,最好用java 实现。,第1张

class

clazz

=

loaderloadclass("combaobaotaoreflectprivatecar");

privatecar

pcar

=

(privatecar)clazznewinstance();

//

package

comtestspringreflect;

虽然类名相同,但包名不同,不是同一个类,所以不能转换。

java中只有类的和包名完全相同,才是同一个类。

改为:

combaobaotaoreflectprivatecar

pcar

=

(combaobaotaoreflectprivatecar)clazznewinstance();

或者

class

clazz

=

loaderloadclass("comtestspringreflectprivatecar");

class Test{

public static void main(String[] args) {

A a = new A();

Systemoutprintln(getValueInField(a,"b1","i"));

Systemoutprintln(getValueInField(a,"b2","i"));

Systemoutprintln(getValueInField(a,"b3","i"));

}

public static Object getValueInField(Object obj,String field,String name){

//三个参数分别是外部的类的对象obj,作为成员属性的类的引用名,要查询的类内部的属性名

try {

Object o = objgetClass()getDeclaredField(field)get(obj);

return ogetClass()getDeclaredField(name)get(o);

} catch (Exception e) {

Systemoutprintln("查找失败");

return null;

}

}

}

class A{

B b1 = new B(1);

B b2 = new B(2);

}

class B{

int i;

B(int i){

thisi = i;

}

}

你的意思就是要获取内部类的属性和方法喽?

Class classes[]=clazzgetDeclaredClasses();//返回类包含的全部内部类

然后再进行处理呗。

Class clazz=XXgetClass();

Class classes[]=clazzgetDeclaredClasses();

for(Class c:classes){//对成员内部类进行反射

int i=cgetModifiers();

String s=ModifiertoString(i);

if(scontains("static"))//静态内部类的处理

cgetConstructor()newInstance();

else//实例内部类的处理

cgetConstructor(ricgetClass())newInstance(ric);

}

//由于匿名内部类没有构建器,因此无法创建实例,也无法直接访问其中的方法,但可以通过下面的方式巧秒的执行其中的方法或成员变量。

Runnable r=(Runnable)(clazzgetField("ta")get(ric));

rrun();

JAVA中,子类可以继承父类的私有属性和方法,但一般不能直接访问,但通过反射还是可以访问的:

import javalangreflectField;

import javalangreflectInvocationTargetException;

import javalangreflectParameterizedType;

import javalangreflectType;

public class A extends B{

public void set(int x) throws Exception{

Field i=((Class< extends A>) thisgetClass()getGenericSuperclass())getDeclaredField("i");

isetAccessible(true);

iset(this, x);

}

public Object get() throws Exception{

Field i=((Class< extends A>) thisgetClass()getGenericSuperclass())getDeclaredField("i");

isetAccessible(true);

return iget(this);

}

public static void main(String[] args) throws Exception{

A a=new A();

Systemoutprintln(aget());

aset(777);

Systemoutprintln(aget());

}

}

public class B {

private int i=100;

}

反射就是把Java的各种成分映射成相应的Java类。

Class类的构造方法是private,由JVM创建。

反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行 *** 作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。(来自Sun)

JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的 *** 作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。

反射是从12就有的,后面的三大框架都会用到反射机制,涉及到类"Class",无法直接new CLass(),其对象是内存里的一份字节码

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

基本的 Java类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法。

Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

Person p1 = new Person();

//下面的这三种方式都可以得到字节码

CLass c1 = Dateclass();

p1getClass();

//若存在则加载,否则新建,往往使用第三种,类的名字在写源程序时不需要知道,到运行时再传递过来

ClassforName("javalangString");

ClassforName()字节码已经加载到java虚拟机中,去得到字节码;java虚拟机中还没有生成字节码 用类加载器进行加载,加载的字节码缓冲到虚拟机中。 

另外,大家可以关注微信公众号Java技术栈回复:JVM,获取我整理的系列JVM教程,都是干货。

考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。

import javalangreflect;

public class DumpMethods {

public static void main(String args[]) {

try {

Class c = ClassforName("javautilStack");

Method m[] = cgetDeclaredMethods();

for (int i = 0; i < mlength; i++)

Systemoutprintln(m[i]toString());

}

catch (Throwable e){

Systemerrprintln(e);

}

}

}

public synchronized javalangObject javautilStackpop()

public javalangObject javautilStackpush(javalangObject)

public boolean javautilStackempty()

public synchronized javalangObject javautilStackpeek()

public synchronized int javautilStacksearch(javalangObject)

这样就列出了javautilStack 类的各方法名以及它们的限制符和返回类型。这个程序使用 ClassforName 载入指定的类,然后调用 getDeclaredMethods 来获取这个类中定义了的方法列表。javalangreflectMethods 是用来描述某个类中单个方法的一个类。

以下示例使用 Class 对象来显示对象的类名:

void printClassName(Object obj) {

Systemoutprintln("The class of " + obj +

" is " + objgetClass()getName());

}

还可以使用一个类字面值(JLS Section 1582)来获取指定类型(或 void)的 Class 对象。例如:

Systemoutprintln("The name of class Foo is: "+FooclassgetName());

在没有对象实例的时候,主要有两种办法。

//获得类类型的两种方式

Class cls1 = Roleclass;

Class cls2 = ClassforName("yuiRole");

注意第二种方式中,forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。现在得到cls1就可以创建一个Role类的实例了,利用Class的newInstance方法相当于调用类的默认的构造器。

Object o = cls1newInstance();

//创建一个实例

//Object o1 = new Role(); //与上面的方法等价

Class c = null;

try {

c = ClassforName("comibmlantestSub");

} catch (ClassNotFoundException e) {

eprintStackTrace();

}

Class superClass = cgetSuperclass();

Field[] fields = superClassgetDeclaredFields();

这是得到父类的属性

for(int i=0;i<fields length;i++)

{

fields [i]setAccessible(true);

Systemoutprintln(fields [i]getType());

fields [i]set();

}

class

c

=

classforname("student");

//通过字符串装载类,

必须是绝对路径,

即包括包名

object

o

=

cnewinstance();

//获取装载类的实例,

如果找不到就会抛出异常

class[]

cs=

{stingclass,intclass};

//定义一个类的数组,

一般这种都是用在method的参数列表

//stringclass说明传的是类型

method

m

=

cgetmethod("study",cs);

//获取装载类的实例的study方法,

注意后面的参数,

class[]

ca

=

{"tom",18}

//和上面有点不同,

这里传的是值

object

result

=

minvoke(o,ca);

//执行method方法,并获取结果

反射一般都用在类名,字段,方法可以随便变化的时候,

还可以进行统一的处理,提高扩展性

比如说hibernate框架的实体类,

预先你不可能知道实体类会有什么字段,

包括字段的类型都是有可能随意变化的,

这时候要获取指定类的字段信息就必须得使用反射了

还有struts的actionform等都一样

以上纯属个人意见,

学得不是很深,希望能给你带来帮助

获得一个类中的方法

先看一下方法和运行结果。获取所有的方法使用Class类中getMethos()方法。

待获取的类:

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

package comaaronreflect;

public class Heros {

private String name;//名字

private String type;//类型

private int camp;//0,近卫;1,天灾

public Heros(){}

public Heros(String name, String type, int camp) {

super();

thisname = name;

thistype = type;

thiscamp = camp;

}

public String getName() {

return name;

}

public void setName(String name) {

thisname = name;

}

public String getType() {

return type;

}

public void setType(String type) {

thistype = type;

}

public int getCamp() {

return camp;

}

public void setCamp(int camp) {

thiscamp = camp;

}

@Override

public String toString() {

return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]";

}

}

Hero类中包含了三个属性,和对应的getter和setter方法。另外还有一个toString方法。这是一个非常常见的pojo。

测试类:

1

2

3

4

5

6

7

8

9

10

11

12

13

package comaaronreflect;

import javalangreflectMethod;

public class Demo5 {

public static void main(String[] args) {

Class<> herosClass = Herosclass;

Method[] methods = herosClassgetMethods();

for (Method method : methods) {

Systemoutprintln(method);

}

}

}

理论上,我们会获得所有的getter和setter,然后还有toString方法

运行结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public void comaaronreflectHerossetType(javalangString)

public int comaaronreflectHerosgetCamp()

public void comaaronreflectHerossetCamp(int)

public javalangString comaaronreflectHerostoString()

public javalangString comaaronreflectHerosgetName()

public void comaaronreflectHerossetName(javalangString)

public javalangString comaaronreflectHerosgetType()

public final void javalangObjectwait(long,int) throws javalangInterruptedException

public final native void javalangObjectwait(long) throws javalangInterruptedException

public final void javalangObjectwait() throws javalangInterruptedException

public boolean javalangObjectequals(javalangObject)

public native int javalangObjecthashCode()

public final native javalangClass javalangObjectgetClass()

public final native void javalangObjectnotify()

public final native void javalangObjectnotifyAll()

然而却列出了这么一大堆。

仔细看一下返回的方法,原来把Object类所拥有的方法也返回了。因为我们这个POJO类默认继承的是javalangObject类。,例如getClass(),equals()这些。

使用getMethods()这个方法,返回了一个包含某些Method对象的数组,Method对象已经介绍过,用来表示一个方法的对象,是对类中方法进行抽象的结果。

这些对象反映了Class对象所表示的类或者接口,当然,包括那些由该类或者接口声明的以及从超类和超接口继承的那些类或接口。举个例子来解释一下:

例如使用getMethods()获得Integer类的方法,会把Integer的父类,Number的所有方法,以及Number的父类Object的方法都获取出来。

这个返回数组,包括了从Object类继承的所有(公共)member方法。返回数组中的元素没有排序。如果这个Class对象表示没有公共成员方法的类或者接口,或者表示了一个基本类型或者表示void,则返回长度为0的数组。

2,调用类中的方法

直接给出一个Demo,注意参数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package comaaronreflect;

import javalangreflectInvocationTargetException;

import javalangreflectMethod;

public class Demo5 {

public static void main(String[] args) {

Class<> herosClass = Herosclass;

try {

Method m1 = herosClassgetMethod("setName",Stringclass);

Method m2 = herosClassgetMethod("getName");

Object userInfo = herosClassnewInstance();

m1invoke(userInfo,"影魔");

Systemoutprintln("调用set方法:"+userInfo);

Systemoutprintln("调用get方法:"+m2invoke(userInfo));

} catch (Exception e) {

eprintStackTrace();

}

}

}

运行结果:

1

2

3

4

5

6

7

8

调用set方法:

Heros [

name=影魔,

type=null,

camp=0

]

调用get方法:

影魔

以上就是关于如何用反射机制访问继承自私有类的方法,最好用java 实现。全部的内容,包括:如何用反射机制访问继承自私有类的方法,最好用java 实现。、java反射获取一个实体类中的另外一个实体类中属性的值,两个实体类是关联关系。、JAVA 反射获取的属性是复合类型等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9688398.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存