首页 > 编程知识 正文

java的反射机制是什么,java的反射机制原理

时间:2023-05-06 01:38:45 阅读:11241 作者:783

反射的机理原理和使用反射的概况:首先不涉及反射是什么,而是谈谈直接反射可以做什么。 例如,在具有三种类型的类(私有方法、私有属性和私有构造函数)中,即使获取了此类的实例对象,也无法根据该对象调用或检索值那么,你可以自省了。 如果有实例,则可以调用内部的所有专用方法和专用属性。 当然,也包括公共级别的。

实例:1.从对象获取类名以创建字符串对象,在getClass (中获取类,在getName )中获取类名,在getSuperclass (获取父类)

String str='hello '; Class aClass=str.getClass (; //class Java.lang.stringsystem.out.println (aclass.getname () ); //Java.lang.stringsystem.out.println (aclass.get super class () ); //class java.lang.Object 2.基本属性的TYPE /** *基本属性的Type和class */Class cx1=int.class; //这种只有classClass cx2=Double.TYPE包装中有typesystem.out.println(CX1 ); //intsystem.out.println(CX2; //double 3.Class.forName ()方法实际上是基于类名初始化的,动态加载和创建Class对象会返回Class对象,这有什么用呢? 实际上,可以基于以后得到的这个class对象来实例化! 实例化的方法是newInstance (),这将在后面进行说明

总的来说,根据类名得到class对象,根据这个class对象String str3='java.lang.String '; //类名class C2=必须为null; try{classC2=class.forname(str3); //返回的是原来是class的Object o=c2.newInstance (; 实例化//system.out.println (C2.getname ) ); system.out.println (C2.get super class ) ); //获取父类}catch(exceptione ) system.out.println ) e; } 4.获取类的构造函数1 )获取所有构造函数在此处定义实体类。 里面有五个不同的构造函数。 四个公共,一个私人

公共类测试{ private int age; 私有字符串名称; 保密测试; 公共测试(intage,String name,int testint ) { this.age=age; this.name=name; this.testint=testint; system.out.println (' name : ' name ' age : ' age ' testint 3360 ' testint ); }公共测试(intage ) { this.age=age; system.out.println(age: ) age; }公共测试(intage,String name ) { this.age=age; this.name=name; system.out.println (' name : ' name ' age : ' age ); }私有测试(string name ) { this.name=name; system.out.println(name: ) name; } public Test () { }} 这里我们来获取这个类所有的构造方法:

在这里,首先实例化对象test,然后在getClass ()中检索其类名。 定义一个构造函数数组,它接收类的所有构造函数。 然后,getDeclaredConstructors (是用于获取类的所有构造函数的getModifiers )方法实际上表明该方法是哪个级别(公共、私有等) 然后使用Modifier.toString ) )方法基于此格式。getParameterTypes ()方法返回class数组,并获取最后输出的方法的参数列表

我知道结果。 确实获得了所有的结构方法。 /**获取类的所有生成方法*/Test test=new Test (); Class cn1=test.getClass (; 构造器[ ]构造器; 用于接受结构方法的结构

器数组 constructor = cn1.getDeclaredConstructors();//返回类的所有构造方法 for(int i = 0; i<constructor.length; i++){ //System.out.println(constructor[i].getModifiers());//这里返回的是一个int //Modifier中的toString方法根据传回来的int来判断方法是什么类型 System.out.print("构造函数类型:"+ Modifier.toString(constructor[i].getModifiers()) +" 参数类型: "); Class[] parameterTypes = constructor[i].getParameterTypes();//获取方法参数列表 for(int j = 0; j < parameterTypes.length; j++){ System.out.print(parameterTypes[j].getName()); } System.out.println(); } //输出如下 构造函数类型:public 参数类型: 构造函数类型:private 参数类型: java.lang.String 构造函数类型:public 参数类型: int java.lang.String 构造函数类型:public 参数类型: int 构造函数类型:public 参数类型: int java.lang.String int 2)获取指定级别的构造函数(这里只获取public的)

其实getConstructors()方法就是只获取public的构造函数,所以跟上面没什么区别

/*** 根据指定的构造方法类型来获取(这里获取的是public级别的)*/Test test1 = new Test();Class cn2 = test1.getClass();Constructor[] constructors1;constructors1 = cn2.getConstructors();for(int i = 0; i<constructors1.length; i++){//Modifier中的toString方法根据传回来的int来判断方法是什么类型System.out.print("构造函数类型:"+ Modifier.toString(constructors1[i].getModifiers()) +" 参数类型: ");Class[] parameterTypes1 = constructors1[i].getParameterTypes();for(int j = 0; j < parameterTypes1.length; j++){ System.out.print(parameterTypes1[j].getName()+" "); } System.out.println(); }//结果:没有私有的构造函数类型:public 参数类型: 构造函数类型:public 参数类型: int java.lang.String 构造函数类型:public 参数类型: int 构造函数类型:public 参数类型: int java.lang.String int 3)获取指定参数列表的构造方法

我们可以通过getDeclaredConstructor()方法传参获取特定参数类型的构造方法,这里注意是getDeclaredConstructor()不是 getDeclaredConstructors() ,所以返回的是一个Class对象而不是一个Class数组。

注意传参即可~!获取无参构造方法直接不传参数

/** * 获取指定参数的构造方法 */Test test2 = new Test();Class cn3 = test2.getClass();try{ Constructor constructor1 =cn3.getDeclaredConstructor(int.class,String.class); System.out.print("构造函数类型:"+ Modifier.toString(constructor1.getModifiers()) +" 参数类型: "); Class[] parameterTypes = constructor1.getParameterTypes(); for(int j = 0; j < parameterTypes.length; j++){ System.out.print(parameterTypes[j].getName()+" "); }}catch (Exception e){ System.out.println(e);} 4)调用构造方法

为了方便查看是否调用了,我们将构造方法中进行输出!

//公有构造方法public Test(int age, String name, int testint){ this.age = age; this.name = name; this.testint = testint; System.out.println("name: "+name+" age: "+age+" testint: "+testint);}//私有构造方法private Test(String name) { this.name = name; System.out.println("name: "+name); }

调用公有构造方法:

我们可以看到,首先获取相应的构造函数,然后用newInstance()方法实例化,只要参数列表对了,就直接调用了类的公有构造方法。

/** * 调用指定的public构造方法 * newInstance实例化 */Test test3 = new Test();Class cn4 = test3.getClass();try{//只要在这修改参数就可以知道是得到的是哪个构造函数 Constructor cons = cn4.getDeclaredConstructor(int.class,String.class,int.class); Object o = cons.newInstance(24, "fanglei",30);//用newInstance方法,得到的是一个对象 System.out.println(o.toString());}catch (Exception e){ System.out.println(e);}//输出name: fanglei age: 24 testint: 30Test{age=24, name='fanglei', testint=30}

调用私有构造方法:

这里和上面是一样的,只不过要多一项cons.setAccessible(true);

/** * 调用私有的构造方法 要设置constructors.setAccessible(true) */Test test4 = new Test();Class cn5 = test4.getClass();try{ Constructor cons = cn5.getDeclaredConstructor(String.class); cons.setAccessible(true); Object o = cons.newInstance("成就的画笔"); System.out.println(o.toString());}catch (Exception e){ System.out.println(e);}//输出name: 成就的画笔Test{age=0, name='成就的画笔', testint=0} 5.获取和调用类的私有成员方法 /** * 私有的成员函数 * @return */private void welcome(String msg){ System.out.println("传入的msg是: "+msg);}

这里和上面就有不同了,这里用的是getDeclaredMethod()函数,第一个参数是方法名,第二个函数参数列表,这时候我们用的就是Method来接收一个方法。然后通过setAccessible(true)来设置,用invoke()方法调用私有方法,第一个参数是对象(也就是调用哪个实例对象的方法),第二个参数就是私有方法的参数列表。

/** * 调用私有的成员函数 */Class[] p ={String.class};Test test5 = new Test();Class cn6 = test5.getClass();try{ //得到私有方法 前面是方法名,后面参数类型 Method method = cn6.getDeclaredMethod("welcome", String.class); method.setAccessible(true);//设置 Object msg[] = {"hello world"};//参数 method.invoke(test5,msg);//用invoke调用方法}catch (Exception e){ System.out.println(e);}//输出传入的msg是: hello world 6.获取私有字段并修改值

这里要清楚,如果没有set,get方法,我们不可能通过一个类的实例去获取和修改类的私有属性的!

这里我们用getDeclaredField方法来获取属性字段,参数是属性名,然后setAccessible(true)设置,之后用set方法来修改属性名,第一个参数是对象名,第二个是参数

/** * 获取类私有字段并修改值 */Test test6 = new Test();Class cn7 = test6.getClass();try{ Field field = cn7.getDeclaredField("name"); field.setAccessible(true); field.set(test6,"fanglei"); System.out.println(test6.toString());}catch (Exception e){ System.out.println(e);}//输出Test{age=0, name='fanglei', testint=0} 总结:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

至于反射里面的其他方法,可以参考这篇文章:

https://www.jianshu.com/p/9be58ee20dee

本篇文章的内容是根据这篇博客打出来的,并不是复制,虽然基本相同,但是都是我手动实现的,为了自己学习的更加深刻:

https://blog.csdn.net/huangliniqng/article/details/88554510

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。