Java反射总结
Posted ming-szu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java反射总结相关的知识,希望对你有一定的参考价值。
反射(java.lang.reflect)用于分析类能力
(一)Class类
1.定义
Java运行时为每一个对象都维护的一个类型标识,用于跟踪对象所属的类提供给虚拟机分析调用,而保存这些信息的类就是Class类
(一个Class类对象可以理解为一个类型,这个类型可以是类或基本数据类型int等)
2.作用
通过对象所属的Class类,我们可以获取对象类型的数据域,方法,父类等一切类信息,还可以用它来创建实例对象
获得父类
//2.获取父类 Class superc1=c1.getSuperclass();
创建实例
//利用反射创建一个实例对象 Class myClass=Class.forName("java.util.Random"); Random random=(Random)myClass.newInstance();
3.获得Class类的3种途径
调用Class的静态方法获取:Class.forName(String className)
对象调用getClass()方法获取Class
通过类型名.class获取,如T.class,T可以是基本数据类型int等,也可以是具体的类如Random.class
Class myClass=Class.forName("java.util.Random"); myClass=new Random().getClass(); myClass=Random.class;
(二)用于描述一个class的三个类:Field,Method,Constructor
Field类代表一个class中的数据域
Method类代表一个class中的方法
Constructor类代表一个class中的构造器
这三个类都继承Accessible
1.获取一个类中的Field,Method,Constructor
Class类调用getDeclaredFields()方法获得该类的所有数据域
Class类调用getDetclaredMethods()方法获得该类的所有方法
Class类调用getDetclaredConstructors()方法获得该类的构造器
2.获得一个Class|Field|Method|Constructor的修饰符
//Modifier.toString()能够获取c1的修饰符public final String modifiers=Modifier.toString(c1.getModifiers());
调用这四个类的getModifiers()方法可以返回一个int,作为参数传入Modifier.toString(),该方法会根据int判断出修饰符
3.获得Field数据域的类型(Class)与Field的名臣
Class classType=f.getType();
String name=f.getName();
4.获取Method的返回类型,Method名称,Method参数类型
String returnType=methods[j].getReturnType().getName(); String methodName=methods[j].getName(); Class[] paraTypes=methods[j].getParameterTypes();
5.打印一个类的具体信息
package Reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * @ClassName ReFlectionTest * @Description 利用反射打印Double类的所有方法 * @Author cherry * @Date 2018/6/9 21:22 * @Update 2018/6/9 21:22 **/ public class ReFlectionTest{ public static void main(String[] argv){ String className="java.lang.Double"; try{ //1.获取Class Class c1=Class.forName(className); //2.获取父类 Class superc1=c1.getSuperclass(); //3.Modifier.toString()能够获取c1的属性public final String modifiers=Modifier.toString(c1.getModifiers()); //4.打印c1的属性 if(modifiers.length()>0)System.out.print(modifiers+" "); //5.打印c1的类名 System.out.print("class "+className); //6.若有继承则打印 if(superc1!=null&&superc1!=Object.class)System.out.print("extends " +superc1.getName()); //7.打印中括号 System.out.print(" { "); //8.打印域 printFields(c1); //9.打印构造器 printConstructors(c1); //10.打印方法 printMethods(c1); //11.打印中括号 System.out.print(" } "); }catch(ClassNotFoundException e){ e.printStackTrace(); } } /** * 打印域 * @param c1 */ public static void printFields(Class c1){ //1.获得所有域 Field[] fields=c1.getFields(); //2.遍历打印 for(Field f:fields){ Class classType=f.getType(); String name=f.getName(); //3.打印进位符 System.out.print(" "); //4.打印属性 String modifiers=Modifier.toString(f.getModifiers()); if(modifiers.length()>0)System.out.print(modifiers+" "); System.out.println(classType+" "+name+";"); } System.out.println(); } /** * 打印传入类的构造器 * @param c1 */ public static void printConstructors(Class c1){ //1.获取所有构造器 Constructor[] constructors=c1.getConstructors(); //2.遍历打印 for(Constructor c:constructors){ //3.打印tab占位符 System.out.print(" "); //4.获取构造器的属性 String modifier=Modifier.toString(c.getModifiers()); if(modifier.length()>0)System.out.print(modifier+" "); //5.打印构造器名 String conName=c.getName(); System.out.print(conName+"("); //6.打印参数 Class[] paraTypes=c.getParameterTypes(); for(int j=0;j<paraTypes.length;j++){ if(j>0)System.out.print(", "); System.out.print(paraTypes[j].getName()); } System.out.print("); "); } System.out.print(" "); } /** * 打印方法 * @param c1 */ public static void printMethods(Class c1){ //1.获取所有的方法 Method[] methods=c1.getMethods(); //2.遍历打印 for(int j=0;j<methods.length;j++){ //3.打印占位符 System.out.print(" "); //4.打印方法属性 String modifiers=Modifier.toString(methods[j].getModifiers()); if(modifiers.length()>0)System.out.print(modifiers+" "); //5.打印返回类型 String returnType=methods[j].getReturnType().getName(); System.out.print(returnType+" "); //6.打印方法名 String methodName=methods[j].getName(); System.out.print(methodName+"("); //7.打印参数名 Class[] paraTypes=methods[j].getParameterTypes(); for(int i=0;i<paraTypes.length;i++){ if(i>0)System.out.print(","); System.out.print(paraTypes[i].getName()); } if(j+1!=methods.length) System.out.print(") "); } } }
(三)运行时获取一个对象的数据域的具体值
Student student=new Student(18); //创建student对象 Class studentClass=student.getClass(); //获取Student的Class Field field=studentClass.getDeclaredField("age"); //得到age域 field.setAccessible(true); //设置可访问private域 System.out.println(field.get(student)); //访问age域的值
(四)调用一个对象的方法
Student student=new Student(18); //创建student对象 Class studentClass=student.getClass(); //获取Student的Class Method setAgeMethod=studentClass.getMethod("setAge", int.class); //获取方法 setAgeMethod.invoke(student,20); //访问age域的值 System.out.println(student.getAge()); //返回20
(五)实现一个泛型数组操作方法
/** * 用于扩展已经填满的数组 * @param a * @param newLength * @return */ public static Object goodCopyOf(Object a,int newLength){ Class c1=a.getClass(); //获取传入的a的Class if(!c1.isArray())return null; //若不是数组类型直接返回null Class compomentType=c1.getComponentType(); //获取数组元素类型 int length=Array.getLength(a); //获取传入的数组的长度 Object newArray=Array.newInstance(compomentType,newLength); //Array.newInstance()根据元素类型与长度新建一个相同类型数组且长度扩大 System.arraycopy(a,0,newArray,0,Math.min(length,newLength)); //将原数组的值赋予新数组 return newArray; }
参考《Java核心技术 卷I》p190
以上是关于Java反射总结的主要内容,如果未能解决你的问题,请参考以下文章