一、基础概念
1、反射(Reflection)就是将一个Java类中的每一个成分解析成一个Java类。
Java类用一个Class类的对象表示,其中一个类的基本组成成分:成员变量、方法、构造方法等信息用一个个的类来表示。而这个类的Class类选举要提供一系列的方法来获取其中的变量、方法等信息,这些信息使用 类的实例对象 来表示, 分别有Field、Constructor、Method、Package等。
其中一个class的成员都可以使用相应的API反射类的对象来表示。
2、得到一个类的Class对象的方法:(1)Person.class;(2)person1.getClass();(3)Class.forName("java.lang.String")。
测试展示部分:
1、Class类:
解释说明:(1)当一个类被载入时,jvm就自动为其生成一个class对象,我们便可以操作一个class对象。
(2)isPrimitive():表示是不是基本数据类型。
补充介绍Java8大基本类型:byte、short、int、long、float、double、boolean、char。
String str = "test";
//三种获取class对象的方法
Class c1 = Class.forName("java.lang.String");
Class c2 = String.class;
Class c3 = str.getClass();
System.out.println(c1 == c2);// true
System.out.println(c1 == c3);// true
System.out.println(c1.isPrimitive()); // false
System.out.println(int.class.isPrimitive()); // true
2、constructor类:
// 获取它所有的构造方法
Constructor[] cs = Class.forName("java.lang.String").getConstructors();
//获得一个指定的构造方法
Constructor<String> constructor = String.class.getConstructor(StringBuffer.class);
String str = constructor.newInstance(new StringBuffer("abc"));
System.out.println(str.toString());// abc
3、Filed类:
一个Pointer类:
public class myPoint{
public int px;
private int py;// 私有
public myPoint(int px, int py){
super();
this.px = px;
this.py = py;
}
public myPoint(){
}
}
通过反射操作获取其相关属性值:
myPoint p1 = new myPoint(1, 2);
// getFiled只能找到公有定义
Field fx = myPoint.class.getField("px");
System.out.println(fx.get(p1));// 1
//无法访问
Field fy = myPoint.class.getField("py");
System.out.println(fy.get(p1));// 报错
以上结果显示无法访问私有属性值,接下来使用暴力反射:
myPoint p1 = new myPoint(1, 2);
// getFiled只能找到公有定义
Field fx = myPoint.class.getField("px");
System.out.println(fx.get(p1));// 1
Field fy = myPoint.class.getDeclaredField("py");
//暴力方法
fy.setAccessible(true);
System.out.println(fy.get(p1));// 2
4、Method类:
利用Method类做charAt(i),其中i是string的具体位置的字符,如hello,我们做str.charAt(1)操作:
String str = "hello";
Method methodCharAt = String.class.getMethod("charAt", int.class);
char target = (char)methodCharAt.invoke(str, 1);// 从0开始
System.out.println(target);// e
二、利用Method、Filed、Constructor获取一个类的相关详细信息
利用Method获取一个类的成员函数的信息:
/**
* 获取类所有的信息:类的成员函数等
* @param obj
*/
public static void printMethodInformation(Object obj){
//按照思路(或者说是步骤):先获得这个类(或者它的对应子类)的类类型
Class c = obj.getClass();
//输出这个类的类名
System.out.println("这个类的名称:"+ c.getName());
/*
* getMethods()方法:返回所有的public类型的方法,包括从父类继承过来的方法
* getDeclaredMethods: 获取所有的自身定义的方法,且不限制方法的类型(或者说是权限:public private protected)
* 获取它所有的方法 : 使用Method类
*/
Method[] ms = c.getMethods();
// 遍历输出这个类方法的相关信息 》 ms获得的是一个类类型, 即可认为是.class
for(Method mm : ms){
//先得到方法返回值类型的类类型
Class returnType = mm.getReturnType();
System.out.print(returnType.getName() + " ");
// 输出方法的名字以及参数的数据类型
System.out.print(mm.getName() + "(");// 方法的名称
//考虑此时可能有多个参数, 再写一个参数数组 :: 此时获取参数列表的类类型
// parameter : 参数、系数、参量
Class[] paraTypes = mm.getParameterTypes();
for(Class o : paraTypes){
//输出参数的数据类型
System.out.print(o.getName() + ",");
}
System.out.println(")");
}
}
测试代码:String s = "nuist"; ClassUtil cu = new ClassUtil; cu.printMethodInformation(s);
输出方法的相关信息:这个类的类名、这个方法的返回值类型、这个方法的方法名以及各参数的数据类型:(参考截图:)
利用Field获取成员量的相关信息:
/**
* 成员变量也是对象
* 获取类所有的信息:类的成员变量, 利用的是一个类Filed, 其中Field类封装了关于成员变量的操作
* @param obj
*/
public static void printFiledInformation(Object obj){
Class c = obj.getClass();
// System.out.println("这个成员变量的名称:"+ c.getName());
/*
* getFields()方法:返回所有的public类型的成员变量
* getDeclaredFields(): 获取所有的自身定义的成员变量的信息
*/
// Field[] f = c.getFields();// java.util.Comparator CASE_INSENSITIVE_ORDER
Field[] f = c.getDeclaredFields();
for(Field field : f){
//先得到成员变量类型的类类型
Class fieldType = field.getType();
//成员变量类型的名字
String typeName = fieldType.getName();
//输出这个成员变量的名字
String fieldName = field.getName();
System.out.println(typeName + " " + fieldName);
}
}
测试代码:Integer in1 = 20; cu.printFiledInformation(in1);
输出成员变量的相关信息:成员变量类型的名称,以及成员变量的变量名:(参考截图:)
利用Constructor获得构造函数的所有内容:
/**
* 获取构造函数的所有的信息:利用的是一个类Constructor, 其中Constructor类封装了关于构造函数的操作
* @param obj
*/
public static void printConstuctorInformation(Object obj){
Class c = obj.getClass();
/*
* getConstructors()方法:返回所有的public类型的构造函数
* getDeclaredConstructors(): 获取所有的自己定义的构造函数的信息
*/
Constructor[] cons = c.getDeclaredConstructors();
for(Constructor con : cons){
//获取构造函数的名称
System.out.print(con.getName() + "(");
//获取构造函数参数变量列表的类类型
Class[] paraTypes = con.getParameterTypes();
for(Class cla : paraTypes){
//输出参数的数据类型
System.out.print(cla.getName() + ",");
}
System.out.println(")");
}
}
测试代码:ClassUtil.printConstuctorInformation("good");
ClassUtil.printConstuctorInformation(new Integer(2));
参考截图:
以上便是这篇的全部内容,欢迎您提出改进意见,谢谢!