1、java 反射的作用(好处):
(1)能够使我们很方便的创建灵活的代码,这些代码可以在运行时装配(运行时获取一个类实例),就不用在组件之间进行源代码链接了,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能。
2、java的反射的负作用:
(1)使用反射的性能较低
(2)使用反射相对来说不安全
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性
3、反射实现要做的事:
(1)反编译:.class->.java
(2)通过反射机制访问java对象的属性,方法,构造方法等。
4、反射要用到的反射机制中的类:
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Method;
java.lang.reflect.Modifider;
5、具体功能的实现:
(1)反射实现的具体方法:下面来获取Demo类型
1)、Clazz1 = Class.forName("Demo");
2) 、 Clazz2 = Demo.class;
3) 、 Demo demo = new Demo();
Clazz3 = demo.getClass();
(2) 创建对象:获取类以后就可以创建对应的对象,利用newInstance;
Class c = Class.forName("Demo");
Object = c.newInstance(); //调用了 Demo的无参数构造方法。
(3)获取属性:包括所有属性和指定属性。
获取所有属性的写法:
package com.test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * Created by Administrator on 2016/11/13. */ public class ClazzTest { public static void main(String [] args){ //获取整个类 try { Class c = Class.forName("java.lang.Integer"); //获取所有的属性 Field[] fs =c.getDeclaredFields(); //定义StringBuffer 来存储属性 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+"{ "); //里边的每一个属性 for (Field field:fs){ stringBuffer.append(" "); stringBuffer.append(Modifier.toString(field.getModifiers())+"");//获得属性的修饰符 stringBuffer.append(field.getType().getSimpleName()+"");//属性类型的名称 stringBuffer.append(field.getName()+"; "); } stringBuffer.append("}"); System.out.print(stringBuffer); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
输出结果:
public final class Integer{ public static final int MIN_VALUE; public static final int MAX_VALUE; public static final ClassTYPE; static final char[] digits; static final char[] DigitTens; static final char[] DigitOnes; static final int[] sizeTable; private final int value; public static final int SIZE; public static final int BYTES; private static final long serialVersionUID; }
获取特定属性:
package com.test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.Integer; /** * Created by Administrator on 2016/11/13. */ public class ClazzTest { public static void main(String [] args){ /* User u = new User(); u.age = 12; //set System.out.println(u.age); //get */ //获取整个类 try { Class c = Class.forName("User"); //获取所有的属性 Field fs =c.getDeclaredField("age"); //不能是静态的属性和final属性 //实例化 Object i = c.getInterfaces(); //打破封装 fs.setAccessible(true); fs.set(i,20); System.out.print(fs.get(i)); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }
获取方法,和构造方法,不再详细描述,只来看一下关键字:
方法关键字 |
含义 |
getDeclaredMethods() |
获取所有的方法 |
getReturnType() |
获得方法的放回类型 |
getParameterTypes() |
获得方法的传入参数类型 |
getDeclaredMethod("方法名",参数类型.class,……) |
获得特定的方法 |
构造方法关键字 |
含义 |
getDeclaredConstructors() |
获取所有的构造方法 |
getDeclaredConstructor(参数类型.class,……) |
获取特定的构造方法 |
父类和父接口 |
含义 |
getSuperclass() |
获取某类的父类 |
getInterfaces() |
获取某类实现的接口 |