您的位置:首页>科学 > 初涉java中的反射

初涉java中的反射

2023-09-26 12:30

笔者是一个小白,在浏览相java相关信息时,总会看到关于java反射相关的讨论,于是花了一个下午的时间在慕课网学习了关于java反射的知识,在这里做一个记录。(虽然现在博客写得水,但是相信慢慢多写多学习还是可以给人一看的)。

以下只贴相关代码,有一篇关于java反射机制的详解博客,待博主同意后贴到此篇结尾。

反射机制的大概模式:万物皆对象,在对类的构造方法,方法,成员变量,均视为对象来访问相关信息

* 打印类的信息,包括类的成员函数,成员变量,构造器* * @author machao* @since Jan 12, 2018*/
public class ClassUtil {/*** 获取成方法对象的信息* * @param obj*/public static void printClassMethodMessage(Object obj) throws Exception {// 要获取的信息,首先获取类的类类型Class c = obj.getClass();// 获取类的名称System.out.println("类的名称是" + c.getName());System.out.println("类的简写名称是" + c.getSimpleName());/** Method类,方法对象 一个成员方法就是一个Method对象* getMethods()方法获取的是所有public的函数,包括父类继承而来的* getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限*/Method[] ms = c.getMethods();// Method m2 = c.getMethod("method", String.class);//// 根据方法名,方法参数类型来获取相关的方法对象for (Method m : ms) {// 得到方法的返回值得类类型Class returnType = m.getReturnType();System.out.println(returnType.getName());// 得到方法的名称System.out.print(m.getName() + "(");// 获取参数类型---->得到的是参数列表的类型的类类型Class[] paramTypes = m.getParameterTypes();for (Class c1 : paramTypes) {System.out.println(c1.getName());}System.out.println(")");}}/*** 获取成员变量对象的信息* * @param obj*/public static void printClassFieldMessage(Object obj) throws Exception {Class c = obj.getClass();/** 成员变量也是对象 java.lang.reflect.Field Field类封装了关于成员变量的操作* getFields()方法获取的是所有的public的成员变量的信息* getDeclaredFields获取的是该类自己声明的成员变量的信息*/Field[] fs = c.getFields();for (Field f : fs) {// 得到成员变量的类类型Class fieldType = f.getType();String typeName = fieldType.getName();// 得到成员变量的名称String filedName = f.getName();System.out.println(typeName + filedName);}}/*** 获取构造方法对象的信息* * @param obj* @throws NoSuchMethodException* @throws SecurityException*/public static void printConstructorMessage(Object obj) throws Exception {Class c = obj.getClass();/** 构造函数也是对象 java.lang. Constructor中封装了构造函数的信息* getConstructors获取所有的public的构造函数 getDeclaredConstructors得到所有的构造函数*/Constructor[] cs = c.getDeclaredConstructors();for (Constructor constructor : cs) {System.out.print(constructor.getName() + "(");// 获取构造函数的参数列表--->得到的是参数列表的类类型Class[] paramTypes = constructor.getParameterTypes();for (Class class1 : paramTypes) {System.out.print(class1.getName() + ",");}System.out.println(")");}// // 获取单个构造器时,如果构造函数有参数,那么这里也需要配置=参数// Constructor con2 = c.getDeclaredConstructor(int.class, String.class);// Student obj1 = (Student) con2.newInstance();//获取新的实例// System.out.println(con2);}
}
其中对于实体类Student,成员变量只有一个int型的age和一个String型的name,构造函数有一个无参构造函数和一个参构造函数,放方法为自动生成的get和set方法。

使用例子:内有一个内部类A,通过访问A的方法对象来实现反射。其中不懂的方法,我是采用直接查询JDK_API,基本都能够看明白,看不明白时再去谷歌百度。

/*** @author machao* @since Jan 12, 2018*/
public class MethodDemo1 {/*** @param args* @throws NoSuchMethodException* @throws SecurityException*/public static void main(String[] args) throws Exception {// TODO Auto-generated method stubA a1 = new A();Class c = a1.getClass();/** 2.获取方法 名称和参数列表来决定  * getMethod获取的是public的方法* getDelcaredMethod自己声明的方法*/// 第一个参数是方法对象的方法名,第二个是方法参数,若干个Method m = c.getMethod("print",int.class,int.class);// 方法的反射操作//a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同//方法如果没有返回值返回null,有返回值返回具体的返回值//Object o = m.invoke(a1,new Object[]{10,20});Object obj = m.invoke(a1, 10, 20);System.out.println("=====================");// 获取方法的print(String,String)Method m1 = c.getDeclaredMethod("print", String.class, String.class);// 用方法进行反射操作// a1.print("hello","world");obj = m1.invoke(a1, "hellow", "world");System.out.println("===================");Method m2 = c.getMethod("print");// m2.invoke(a1, new Object[]{});m2.invoke(a1);}
}class A {public void print() {System.out.println("helloworld");}public void print(int a, int b) {System.out.println(a + b);}public void print(String a, String b) {System.out.println(a.toUpperCase() + "," + b.toLowerCase());}
}



关于反射机制的一个使用

public class MethodDemo4 {public static void main(String[] args) {ArrayList list = new ArrayList();ArrayList list1 = new ArrayList();list1.add("hello");//list1.add(20);错误的Class c1 = list.getClass();Class c2 = list1.getClass();System.out.println(c1 == c2);//反射的操作都是编译之后的操作/** c1==c2结果返回true说明编译之后集合的泛型是去泛型化的* Java中集合的泛型,是防止错误输入的,只在编译阶段有效,* 绕过编译就无效了* 验证:我们可以通过方法的反射来操作,绕过编译*/try {Method m = c2.getMethod("add", Object.class);m.invoke(list1, 20);//绕过编译操作就绕过了泛型System.out.println(list1.size());System.out.println(list1);/*for (String string : list1) {System.out.println(string);}*///现在不能这样遍历} catch (Exception e) {e.printStackTrace();}}}

致谢

     慕课网:https://www.webguidecorpuschristi.com/video/3725

     用户[蓝莲花wsg]: http://www.webguidecorpuschristi.com/qq_29375837/article/details/78521033