Java反射机制学习总结
来源:互联网 发布:美团众包辅助软件 编辑:程序博客网 时间:2024/05/16 16:15
定义一、能够分析类能力的程序成为反射。(核心卷一定义)
定义二、 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。(网上找的定义义)
反射机制可以用来:
在运行中分析类的能力。
在运行中查看对象。
实现通用的数组操作代码
利用Method对象,这个对象很想c++中的函数指针。
一、利用反射分析类的能力
1、反射机制最重要的内容——检查类的结构
sun为我们提供了那些反射机制中的类:
java.lang.Class;
java.lang.reflect.Constructor; java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
在java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的域、方法和构造器。这三个类都有一个叫做getName的方法,用于返回项目的名称。
Field类有一个getType方法,用来返回描述域所属类型的Class对象。Method和Constructor类有能够报告参数类型的方法,Method类还有一个可以报告返回类型的方法。这三个类还有一个叫做getModifiers的方法,它将返回一个整型数值,用不同的位开关描述public和static这样的修饰符使用状况。
Class类中的getField,getMethod和getConstructors方法将分别返回类提供的public域、方法和构造器数组,其中包括超累的公有成员。Class类的getDeclareField、getDeclareMethods和getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护成员,但不包括超累的成员。
一、Class类的使用
package com.slowly.reflectTest;import java.lang.reflect.Method;class MyFather { public int fatherMember; public void methodFather(){ System. out.println( "我是从父类继承而来的方法methodFather" ); }}class Son extends MyFather{ public int sonMemberpublic; @SuppressWarnings( "unused") private int sonMemberprivate; public void methodSon(){ System. out.println( "我是子类自己的方法!" ); } protected void methodsonProtected(){ System. out.println( "我是子类受保护的方法!!" ); }}public class reflectsample{ public static void main(String[] args) { try { /* * 获取c可以有如下两种方法 * */ //第一种推荐使用 Class c = Class.forName( "com.slowly.reflectTest.Son"); /*第二种不推荐使用 Son son = new Son(); Class c = son.getClass(); */ Son s = (Son) c.newInstance(); System. out.println( "=======调用创建对象的方法=======" ); s.methodsonProtected(); s.methodSon(); s.methodFather(); //打印加载类的详细信息 System. out.println( "=====加载类的详细信息======" ); System. out.println( c.getName()+ "类自己声明了" +c .getDeclaredFields().length +"个成员变量" ); System. out.println( "类自己公布的方法有" +c .getMethods().length +"个" ); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
输出结果:
Field类的例子
import java.lang.reflect.*;class Student{ public int age; private int id; public boolean gender; public String name; public Student( int age, int id, boolean gender,String name){ this. age = age; this. id = id; this. gender = gender; this. name = name; }}public class Field { public static void main(String[] args) { Student tom = new Student(21,1001, true, "Tom"); //获取Student对应的Class类对象 Class c = tom.getClass(); //获取Student类所有可以访问的成员变量对应的Filed数组 java.lang.reflect.Field[] fieldarray = c.getFields(); //打印Student类对象各成员变量的详细信息 System. out.println( "成员变量名\t\t成员变量类型\t\t成员变量值" ); int size = fieldarray. length; //循环处理Filed数组 for ( int i = 0; i< size; i++) { java.lang.reflect.Field tempf = fieldarray[i]; //打印输出成员变量名称 System. out.print( tempf.getName()+ "\t\t"); //打印成员变量类型 System. out.print( tempf.getType().toString() +( tempf.getType().toString().length()>7? "\t": "\t\t")); try { //打印成员变量值 System. out.println( tempf.get( tom)); } catch (IllegalArgumentException | IllegalAccessException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
显示结果:
可以看出,程序打印了正确的成员变量信息,包括age、gender、name成员变量。
而id由于是私有成员,不能在Student类外访问,因此没有打印。
三、Method的介绍及例子
对于invoke()方法有如下几点需要注意
不管实际对应方法的返回值为什么类型,都作为Object类型返回。若返回为基本数据类型,则返回对应封装类的对象。
obj参数指出要被调用方法所属的对象,若调用静态的方法用null值。
args指出要被调用方法的参数序列,若方法没有参数则传递空数组---new Object[0],若方法有基本数据类型的参数则使用基本数据类型的封装对象。
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;class ForMethod{ //声明静态方法 public static void sayHello(String name){ System. out.println( "你好" +name +"!!!" ); } public String generateNum( int max, int min){ return (Math. random()*( max- min)+ min)+ ""; }}public class method { public static void main(String[] args) throws Exception { //创建ForMethod类对象 ForMethod fm = new ForMethod(); //获取ForMethod类对象对用的Class对象 Class fmc = fm.getClass(); //获取可以访问的对象的对应的Method数组 Method[] md = fmc.getMethods(); System. out.println( "方法名称\t\t返回值类型\t\t参数列表" ); int size = md. length; for( int i = 0; i< size; i++){ Method tempm = md[ i]; //打印方法名称 String name = tempm.getName(); System. out.print( name+( name.length()>7? "\t": "\t\t")); //打印方法的返回值类型 String returntype = tempm.getReturnType().getName(); System. out.print( returntype+(( returntype.length()>15)? "\t":( returntype.length()>10)? "\t\t": "\t\t\t")); //打印方法的参数序列 Class[] ca = tempm.getParameterTypes(); int csize = ca. length; if( csize==0){ System. out.println( "没有参数!!" ); } else for( int j = 0; j< csize; j++){ System. out.print( ca[ j].getName()+(( j== csize-1)? "": ",")); } //换行 System. out.println(); } System. out.println( "=====通过反射调用静态方法sayHello======" ); md[0].invoke( null, new Object[]{ "王强" }); //通过反射调用非静态方法 System. out.println( "=====通过反射调用非静态方法generateNum=======" ); System. out.println( md[1].invoke( fm, new Object[]{new Integer(100),new Integer(1000)})); }}输出结果:
四、Constructor类的知识与应用
Consstructor类的对象代表一个构造器,携带构造器的相关信息,与Field、Method·类类似,其对象也不能通过构造器创建,而是要使用Class对象提供的get()系列方法获得。
例子:
import java.lang.reflect.Constructor;class Student01{ String name; int age; //无参构造器 public Student01(){ name = "Tom"; age = 23; } //有参构造器 public Student01(String name, int age){ this. name = name; this. age = age; } public void sayHello(){ System. out.println( "您好,我是" +name +"今年" +age +"岁了!" ); }}public class constructor { public static void main(String[] args) { try{ //获取Student类的Class对象 Class sc = Student01. class; //获取可以访问构造器对应的Constructor数组 Constructor[] ca = sc.getConstructors(); //对数组进行扫描打印构造器信息 System. out.println( "构造器名\t\t\t\t\t\t参数列表" ); int size = ca. length; //System.out.println(size+""); for( int i = 0; i< size; i++){ Constructor tempc = ca[ i]; //打印构造器的名字 String cname = tempc.getName(); System. out.print( cname+ "\t\t"); //循环打印构造器的序列参数 Class[] pm = tempc.getParameterTypes(); int psize = pm. length; if( psize==0){ System. out.println( "没有参数!" ); } else for( int j = 0; j< psize; j++){ System. out.print( pm[ j].getName()+(( j== psize-1)? "": ",")); } //换行 System. out.println(); } //使用反射调用无参构造器 Student01 stu = (Student01) ca[0].newInstance( new Object[0]); //调用创建对象的方法 stu.sayHello(); //使用反射调用有参构造器 Student01 stu01 = (Student01) ca[1].newInstance( "王强" ,new Integer(25)); //调用创建对象的方法 stu01.sayHello(); } catch(Exception e){ e.printStackTrace(); } }}运行结果:
0 0
- java反射机制学习总结
- java反射机制学习总结
- java反射机制学习总结
- JAVA反射机制学习总结
- Java学习总结:反射机制
- Java反射机制学习总结
- Java反射机制——学习总结
- Java反射机制——学习总结
- Java反射机制——学习总结
- Java反射机制总结学习--Class类
- Java反射机制——学习总结
- java中的反射机制-1(学习总结)
- 反射机制学习总结
- Java反射机制总结
- java反射机制总结
- Java反射机制总结
- Java 反射机制总结
- Java反射机制总结
- apache-apollo 树莓派构建物联网
- Android studio 导入另外一个项目作为依赖包问题集锦!!!
- 数据结构实验之图论四:迷宫探索
- VS系统项目添加代码模板 主要是controller和view选择支架模板
- 遥感图像处理步骤
- Java反射机制学习总结
- 2级联动过程中出现的bug
- java常见类
- 详解Pyqt中设置图标
- Linux常用指令(更新中)
- 进入标签的世界JSTL与EL深入研究
- 数据结构实验之查找三:树的种类统计
- Android Dagger2 MVP架构 一看就明白
- 郭晶晶霍启刚夫妇,一股豪门清流