什么网站可以直接做word文档,营销推广外包公司,中国建筑网信息网,分销商管理系统目录 一 概述二 反射的三种方式1、通过已实例化的java对象获取#xff1a;xxx.getClass()2、通过类名获取#xff1a;xxx.class3、通过类的全路径获取#xff1a;Class.forName(xxx) 三 获取并使用类的构造方法1、获取构造方法#xff1a;2、调用构造方法… 目录 一 概述二 反射的三种方式1、通过已实例化的java对象获取xxx.getClass()2、通过类名获取xxx.class3、通过类的全路径获取Class.forName(xxx) 三 获取并使用类的构造方法1、获取构造方法2、调用构造方法 四 获取并设置类的成员变量五 获取并调用类的成员方法1、获取指定方法2、调用指定方法 六 获取并调用主函数七 反射的其他用法1、通过反射运行配置文件内容——示例 2、通过反射越过泛型检查 一 概述
Java反射说的是在运行状态中对于任何一个类我们都能够知道这个类有哪些方法和属性。对于任何一个对象我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。
所谓反射其实是获取类的字节码文件也就是.class文件通过Class这个对象进行获取。
Class 类的实例表示正在运行的 Java类和接口jvm中每个类都有且只有一个class对象。包括基本数据类型
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建JVM已经帮我们创建好了。
二 反射的三种方式
获取类的字节码文件有三种方式
1、通过已实例化的java对象获取xxx.getClass()
getClass()是Object的一个方法Class继承了Object所以我们可以直接使用
Travel travelnew Travel();
Class ctravel.getClass();2、通过类名获取xxx.class
Class cTravel.class;3、通过类的全路径获取Class.forName(“xxx”) try {Class cClass.forName(com.suixing.pojo.Travel)} catch (ClassNotFoundException e) {e.printStackTrace();}因为运行期间一个类只会有一个class对象产生所以用不同方式多次获取同一个类的class对象所获取到是同一个class对象
三 获取并使用类的构造方法
1、获取构造方法
1批量的方法 public Constructor[] getConstructors()所有”公有的”构造方法 public Constructor[] getDeclaredConstructors()获取所有的构造方法(包括私有、受保护、默认、公有)
2获取单个的方法并调用 public Constructor getConstructor(Class… parameterTypes):获取单个的”公有的”构造方法 public Constructor getDeclaredConstructor(Class… parameterTypes):获取”某个构造方法”可以是私有的或受保护、默认、公有
2、调用构造方法
Constructor对象.newInstance(Object… initargs)
newInstance(Object… initargs)使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例并用指定的初始化参数初始化该实例。 它的返回值是T类型所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用
public static void main(String[] args) throws NoSuchMethodException {try {Class cClass.forName(com.suixing.pojo.TestPojo);System.out.println(***************所有公有构造方法******************);Constructor[] constructorsc.getConstructors();for(Constructor constructor : constructors){System.out.println(constructor);}System.out.println(*********所有的构造方法(包括私有、受保护、默认、公有)*********);constructors c.getDeclaredConstructors();for(Constructor constructor : constructors){System.out.println(constructor);}System.out.println(**********获取公有、无参的构造方法***************);Constructor constructor c.getConstructor(null);//因为是无参的构造方法所以类型是一个null,不写也可以System.out.println(constructor);System.out.println(***********获取私有构造方法并调用*************);constructor c.getDeclaredConstructor(Integer.class);System.out.println(constructor);constructor.setAccessible(true);//暴力访问(忽略掉访问修饰符)Object o constructor.newInstance(21);System.out.println(o.toString());System.out.println(**************获取并调用多参数的公有构造方法***********);constructorc.getConstructor(new Class[]{String.class,String.class,Integer.class});o constructor.newInstance(ximou,661,21);System.out.println(o.toString());} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}四 获取并设置类的成员变量 //c是Class类的对象System.out.println(************获取所有公有的字段********************);Field[] fieldsc.getFields();for(Field field:fields)System.out.println(field);System.out.println(************获取所有的字段********************);fieldsc.getDeclaredFields();for(Field field:fields)System.out.println(field);System.out.println(**************获取私有字段并调用**************);Field fieldc.getDeclaredField(name);field.setAccessible(true);field.set(o,change name);System.out.println(o.toString());设置字段时需要传递两个参数一个是实体类对象一个是要设置的值
//f是Field对象
Object obj stuClass.getConstructor().newInstance();
f.set(obj, “刘德华”);五 获取并调用类的成员方法 System.out.println(***********获取所有的”公有“方法*************);c.getMethods();Method[] methodArray c.getMethods();for(Method m : methodArray){System.out.println(m);}System.out.println(*************获取所有的方法包括私有的***********);methodArray c.getDeclaredMethods();for(Method m : methodArray){System.out.println(m);}System.out.println(***************获取公有的show1()方法*******************);Method methodc.getMethod(show1,String.class);Object resultmethod.invoke(o,(123456));System.out.println(return result);System.out.println(***************获取私有的show4()方法******************);methodc.getDeclaredMethod(show4,int.class);method.setAccessible(true);resultmethod.invoke(o,123);System.out.println(return result);System.out.println(***************获取默认的、多个参数的show3()方法******************);methodc.getDeclaredMethod(show3,String.class,int.class);method.setAccessible(true);resultmethod.invoke(o,sss,123);System.out.println(return result);1、获取指定方法
需要传入至少两个参数第一个是调用的方法名称第二个到第n个是方法的形参类型切记是类型。
m stuClass.getDeclaredMethod(“show4”, int.class);2、调用指定方法
需要至少两个参数一个是要调用的对象其他的是实参
m.setAccessible(true);//对非公有方法解除私有限定
Object result m.invoke(obj, 20);六 获取并调用主函数 Method methodc.getMethod(main,String[].class);method.invoke(null,(Object)new String[]{a,b});七 反射的其他用法
1、通过反射运行配置文件内容
假设有两个业务类
public class Service1 {public void doService1(){System.out.println(业务方法1);}
}public class Service2 {public void doService2(){System.out.println(业务方法2);}
}当需要从第一个业务方法切换到第二个业务方法的时候若使用非反射方式则必须修改代码并且重新编译运行才可以达到效果
public class CommonTest {public static void main(String[] args) {//new Service1().doService1();//必须重新修改代码new Service2().doService2();}
}而使用反射方式则方便很多
——示例
spring.txt
classreflection.Service1
methoddoService1测试类
public class ReflectTest {SuppressWarnings({ rawtypes, unchecked })public static void main(String[] args) throws Exception {Properties pro new Properties();FileReader in new FileReader(spring.txt);//获取输入流,从spring.txt中获取类名称和方法名称pro.load(in);in.close();String className (String) pro.get(class);String methodName (String) pro.get(method);//根据类名称获取类对象Class clazz Class.forName(className);//根据方法名称获取方法对象Method m clazz.getMethod(methodName);//获取构造器Constructor c clazz.getConstructor();//根据构造器实例化出对象Object service c.newInstance();//调用对象的指定方法m.invoke(service); }
}2、通过反射越过泛型检查
泛型是在编译期间起作用的。在编译后的.class文件中是没有泛型的。所有比如T或者E类型啊本质都是通过Object处理的。所以可以通过使用反射来越过泛型。
public class GenericityTest {public static void main(String[] args) throws Exception{ArrayListString list new ArrayList();list.add(this);list.add(is);//list.add(5);报错/********** 越过泛型检查 **************///获取ArrayList的Class对象反向的调用add()方法添加数据Class listClass list.getClass(); //获取add()方法Method m listClass.getMethod(add, Object.class);//调用add()方法m.invoke(list, 5);//遍历集合for(Object obj : list){System.out.println(obj);}}
}