JAVA编码(36)—— Java反射机制详解
package com.sinosoft.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Reflect { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException, SecurityException, NoSuchMethodException { //通过反射机制获取类的包名及类名 Demo1(); System.out.println("================================="); //验证所有的类都是Class类的实例对象 Demo2(); System.out.println("================================="); //通过反射机制,用class创建类对象[这也是反射存在的意义所在] Demo3(); System.out.println("================================="); //通过反射机制,得到一个类的构造函数,并实现创建带参实例对象 Demo4(); System.out.println("================================="); //通过反射机制,来操作成员变量,get和set方法 Demo5(); System.out.println("================================="); //通过反射机制,得到类的一些属性:继承的接口,父类,函数信息,成员信息,类型等 Demo6(); System.out.println("================================="); //通过反射机制,调用类方法 Demo7(); System.out.println("================================="); //通过反射机制,得到类加载器信息 Demo8(); System.out.println("================================="); } /** * 通过java反射机制,得到类加载器信息 * 在java中,存在三种类加载器信息: * @throws ClassNotFoundException * */ private static void Demo8() throws ClassNotFoundException { // TODO Auto-generated method stub Class<?> class1 = null; class1 = Class.forName("com.sinosoft.reflect.SuperMan"); String url = class1.getClassLoader().getClass().getName(); System.out.println("类加载器名:"+url); } /** * 通过java反射机制,调用类方法,并执行方法体 * @throws ClassNotFoundException * @throws SecurityException * @throws NoSuchMethodException * @throws InstantiationException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException */ private static void Demo7() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { // TODO Auto-generated method stub Class<?> class1 = null; class1 = Class.forName("com.sinosoft.reflect.SuperMan"); System.out.println("Demo7: \n调用无参方法fly():"); Method method = class1.getMethod("fly"); method.invoke(class1.newInstance()); System.out.println("调用有参方法walk(int m):"); method = class1.getMethod("walk", int.class); method.invoke(class1.newInstance(), 1000); } /** * 根据java反射机制,来获取类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等 * @throws ClassNotFoundException */ private static void Demo6() throws ClassNotFoundException { // TODO Auto-generated method stub Class<?> class1 = null; class1 = Class.forName("com.sinosoft.reflect.SuperMan"); //取得父类的名称 Class<?> superClass = class1.getSuperclass(); System.out.println("superMan父类的名称:"+superClass.getName()); //取得成员变量 Field[] fields = class1.getDeclaredFields(); for (Field field : fields) { System.out.println("类中的成员:"+field); } //取得类方法 Method[] methods = class1.getDeclaredMethods(); System.out.println("取得SuperMan类中的方法:"); for (Method method : methods) { System.out.println("方法名:"+method.getName()); System.out.println("方法返回类型:"+method.getReturnType()); System.out.println("方法访问修饰符:" + Modifier.toString(method.getModifiers())); System.out.println("方法代码写法:"+method); } //取得类实现的接口,因为接口类也属于Class,所以得到接口中的方法也是一样的方法得到哈 Class<?>[] interfacesClasses = class1.getInterfaces(); for (Class<?> class2 : interfacesClasses) { System.out.println("接口类名:"+class2.getName()); } } /** * 通过java反射机制,来操作成员变量,get和set方法 * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws SecurityException * @throws NoSuchFieldException */ private static void Demo5() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException { // TODO Auto-generated method stub Class<?> class1 = null; class1 = Class.forName("com.sinosoft.reflect.Person"); Object object = class1.newInstance(); Field nameField = class1.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(object, "huachunjie"); System.out.println("修改属性后得到属性的值:"+nameField.get(object)); } /** * 通过java反射机制,得到一个类的构造函数,并实现创建带参实例 * @throws ClassNotFoundException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstantiationException */ private static void Demo4() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub Class<?> class1 = null; Person person1 = null; Person person2 = null; class1 = Class.forName("com.sinosoft.reflect.Person"); //得到一系列的构造函数 Constructor<?>[] constructor = class1.getConstructors(); System.err.println(constructor.length); person1 = (Person) constructor[0].newInstance(); person1.setAge(30); person1.setName("xiaogao"); person2 = (Person) constructor[1].newInstance(40, "laogao"); System.out.println("获取person1对象属性值:age:"+person1.getAge()+" name:"+person1.getName()); System.out.println("获取person2对象属性值:age:"+person2.getAge()+" name:"+person2.getName()); } /** * 通过java反射机制,用class创建类对象 * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ private static void Demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // TODO Auto-generated method stub Class<?> class1 = null; class1 = Class.forName("com.sinosoft.reflect.Person"); //由于这里不能带参数,所以你要实例化这个Person,一定要有无参构造函数 Person person = (Person) class1.newInstance(); person.setAge(20); person.setName("xushuyi"); System.out.println("通过反射机制来修改属性值:age:"+person.getAge()+" name:"+person.getName()); } /** * 验证所有的类都是class类的实例对象 * @throws ClassNotFoundException */ private static void Demo2() throws ClassNotFoundException { // TODO Auto-generated method stub Class<?> class1 = null; Class<?> class2 = null; //写法1 class1 = Class.forName("com.sinosoft.reflect.Person"); System.out.println("包名:"+class1.getPackage().getName()); System.out.println("完成类名:"+class1.getName()); //写法2 class2 = Person.class; System.out.println("包名:"+class2.getPackage().getName()); System.out.println("完整类名:"+class2.getName()); } /** * 根据java反射机制获取类的包名及类名 */ private static void Demo1() { // TODO Auto-generated method stub Person person = new Person(); System.out.println("Person 包名:"+person.getClass().getPackage().getName()); System.out.println("Person 类名:"+person.getClass().getName()); } } class SuperMan extends Person implements ActionInterface { private boolean BlueBriefs; public void fly(){ System.out.println("超人会飞了耶。。。"); } @Override public void walk(int m) { // TODO Auto-generated method stub System.out.println("超人会走耶~~走了" + m + "米就走不动了!"); } public boolean isBlueBriefs() { return BlueBriefs; } public void setBlueBriefs(boolean blueBriefs) { BlueBriefs = blueBriefs; } } /** * 定义一个实体类 * @author fanyb * */ class Person{ private int age; private String name; public Person() { // TODO Auto-generated constructor stub } public Person(int age, String name) { super(); this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } /** * 定义一个接口 * @author fanyb * */ interface ActionInterface{ public abstract void walk(int m); }
反射机制,其实就是把一个类,类的成员(函数、属性)当成一个对象来操作。也就是说类、类的成员在我们运行的时候能够动态的操作他们。
反射机制一般运用的地方:
1.工厂模式:Factory类中用反射的话,添加一个新的类之后,就不需要再去修改Factory类了
2.数据库JDBC,通过Class.forName(Driver);来获取数据库连接驱动
3.分析类文件,毕竟能够得到类中的方法等等
4.访问一些不能够访问的变量或属性,破解别人的代码

浙公网安备 33010602011771号