Java 反射
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
优点:
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能
缺点:
(1)使用反射的性能较低
(2)使用反射相对来说不安全
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
方法关键字 getDeclaredMethods() 获取所有的方法 getReturnType() 获得方法的放回类型 getParameterTypes() 获得方法的传入参数类型 getDeclaredMethod("方法名",参数类型.class,……) 获得特定的方法 构造方法关键字 getDeclaredConstructors() 获取所有的构造方法 getDeclaredConstructor(参数类型.class,……) 获取特定的构造方法 父类和父接口 getSuperclass() 获取某类的父类 getInterfaces() 获取某类实现的接口
1.通过对象获取完整的包名和类名
package com.qhong; public class Main { public static void main(String[] args) { TestReflect testReflect = new TestReflect(); System.out.println(testReflect.getClass().getName()); } } class TestReflect {}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
com.qhong.TestReflect
实例化class的对象
package com.qhong; public class Main { public static void main (String[] args) throws Exception{ Class<?> class1 = null; Class<?> class2 = null; Class<?> class3 = null; // 一般采用这种形式 class1 = Class.forName("com.qhong.TestReflect"); class2 = new TestReflect().getClass(); class3 = TestReflect.class; System.out.println("类名称 " + class1.getName()); System.out.println("类名称 " + class2.getName()); System.out.println("类名称 " + class3.getName()); } } class TestReflect {}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
类名称 com.qhong.TestReflect
类名称 com.qhong.TestReflect
类名称 com.qhong.TestReflect
获取一个对象的父类已经继承的接口
package com.qhong; import java.io.Serializable; public class Main { public static void main (String[] args) throws Exception{ Class<?> cla= Class.forName("com.qhong.TestReflect"); // 取得父类 Class<?> parentClass = cla.getSuperclass(); System.out.println("cla的父类为:" + parentClass.getName()); // 获取所有的接口 Class<?> interfaces[] = cla.getInterfaces(); System.out.println("cla实现的接口有:"); for (int i = 0; i < interfaces.length; i++) { System.out.println((i + 1) + ":" + interfaces[i].getName()); } } } class TestReflect implements Serializable {}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
cla的父类为:java.lang.Object
cla实现的接口有:
1:java.io.Serializable
通过反射实例化一个对象(获取类的全部构造函数)
import java.io.Serializable; import java.lang.reflect.Constructor; public class Main { public static void main (String[] args) throws Exception{ Class<?> class1 = null; class1 = Class.forName("com.qhong.User"); // 第一种方法,实例化默认构造方法,调用set赋值 User user = (User) class1.newInstance(); user.setAge(20); user.setName("Rollen"); System.out.println(user); System.out.println("==========================="); // 第二种方法 取得全部的构造函数 使用构造函数赋值 Constructor<?> cons[] = class1.getConstructors(); // 查看每个构造方法需要的参数 for (int i = 0; i < cons.length; i++) { Class<?> clazzs[] = cons[i].getParameterTypes(); System.out.print("cons[" + i + "] ("); for (int j = 0; j < clazzs.length; j++) { if (j == clazzs.length - 1) System.out.print(clazzs[j].getName()); else System.out.print(clazzs[j].getName() + ","); } System.out.println(")"); if(clazzs.length==1) { user = (User) cons[i].newInstance("Rollen"); System.out.println(user); } if(clazzs.length==2){ user = (User) cons[i].newInstance(20, "Rollen"); System.out.println(user); } System.out.println("==========================="); } } } class TestReflect implements Serializable {} class User { private int age; private String name; public User() { super(); } public User(String name) { super(); this.name = name; } public User(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; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
User [age=20, name=Rollen] =========================== cons[0] (int,java.lang.String) User [age=20, name=Rollen] =========================== cons[1] (java.lang.String) User [age=0, name=Rollen] =========================== cons[2] () ===========================
获取某个类以及其父类的全部属性
import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Main { public static void main (String[] args) throws Exception{ Class<?> clazz = Class.forName("com.qhong.TestReflect"); System.out.println("===============本类属性==============="); // 取得本类的全部属性 Field[] field = clazz.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 权限修饰符 int mo = field[i].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = field[i].getType(); System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";"); } System.out.println("==========实现的父类的属性=========="); // 取得实现的接口或者父类的属性 Field[] filed1 = clazz.getSuperclass().getDeclaredFields(); for (int j = 0; j < filed1.length; j++) { // 权限修饰符 int mo = filed1[j].getModifiers(); String priv = Modifier.toString(mo); // 属性类型 Class<?> type = filed1[j].getType(); System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";"); } } } class TestReflect extends User implements Serializable { private static final long serialVersionUID = -2862585049955236662L; } class User { private int age; private String name; public User() { super(); } public User(String name) { super(); this.name = name; } public User(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; } @Override public String toString() { return "User [age=" + age + ", name=" + name + "]"; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
===============本类属性=============== private static final long serialVersionUID; ==========实现的父类的属性========== private int age; private java.lang.String name;
获取某个类的全部方法:
import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Main { public static void main (String[] args) throws Exception{ Class<?> clazz = Class.forName("com.qhong.TestReflect"); Method method[] = clazz.getMethods(); for (int i = 0; i < method.length; ++i) { Class<?> returnType = method[i].getReturnType(); Class<?> para[] = method[i].getParameterTypes(); int temp = method[i].getModifiers(); System.out.print(Modifier.toString(temp) + " "); System.out.print(returnType.getName() + " "); System.out.print(method[i].getName() + " "); System.out.print("("); for (int j = 0; j < para.length; ++j) { System.out.print(para[j].getName() + " " + "arg" + j); if (j < para.length - 1) { System.out.print(","); } } Class<?> exce[] = method[i].getExceptionTypes(); if (exce.length > 0) { System.out.print(") throws "); for (int k = 0; k < exce.length; ++k) { System.out.print(exce[k].getName() + " "); if (k < exce.length - 1) { System.out.print(","); } } } else { System.out.print(")"); } System.out.println(); } } } class TestReflect { private static final long serialVersionUID = -2862585049955236662L; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public final void wait () throws java.lang.InterruptedException public final void wait (long arg0,int arg1) throws java.lang.InterruptedException public final native void wait (long arg0) throws java.lang.InterruptedException public boolean equals (java.lang.Object arg0) public java.lang.String toString () public native int hashCode () public final native java.lang.Class getClass () public final native void notify () public final native void notifyAll ()
通过反射调用类中的方法:
import java.lang.reflect.Method; public class Main { public static void main (String[] args) throws Exception { Class<?> clazz = Class.forName("com.qhong.TestReflect"); // 调用TestReflect类中的reflect1方法 Method method = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); // Java 反射机制 - 调用某个类的方法1. // 调用TestReflect的reflect2方法 method = clazz.getMethod("reflect2", int.class, String.class); method.invoke(clazz.newInstance(), 20, "张三"); } } class TestReflect { private static final long serialVersionUID = -2862585049955236662L; public void reflect1() { System.out.println("Java 反射机制 - 调用某个类的方法1."); } public void reflect2(int age, String name) { System.out.println("Java 反射机制 - 调用某个类的方法2."); System.out.println("age -> " + age + ". name -> " + name); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Java 反射机制 - 调用某个类的方法1. Java 反射机制 - 调用某个类的方法2. age -> 20. name -> 张三
通过反射机制操作类的属性
import java.lang.reflect.Field; public class Main { public static void main (String[] args) throws Exception { Class<?> clazz = Class.forName("com.qhong.TestReflect"); Object obj = clazz.newInstance(); // 可以直接对 private 的属性赋值 Field field = clazz.getDeclaredField("proprety"); field.setAccessible(true); field.set(obj, "Java反射机制"); System.out.println(field.get(obj)); } } class TestReflect { private static final long serialVersionUID = -2862585049955236662L; private String proprety = null; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Java反射机制
反射机制的动态代理:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 在java中有三种类类加载器。 * * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 * * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类 * * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 * * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。 * */ public class Main { public static void main (String[] args) throws Exception { // 获取类加载器的方法 TestReflect testReflect = new TestReflect(); System.out.println("类加载器 " + testReflect.getClass().getClassLoader().getClass().getName()); MyInvocationHandler demo = new MyInvocationHandler(); Subject sub = (Subject) demo.bind(new RealSubject()); String info = sub.say("Rollen", 20); System.out.println(info); } } class TestReflect { private static final long serialVersionUID = -2862585049955236662L; private String proprety = null; } //定义项目接口 interface Subject { public String say(String name, int age); } // 定义真实项目 class RealSubject implements Subject { public String say(String name, int age) { return name + " " + age; } } class MyInvocationHandler implements InvocationHandler { private Object obj = null; public Object bind(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object temp = method.invoke(this.obj, args); return temp; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
类加载器 sun.misc.Launcher$AppClassLoader
Rollen 20
===========================================================================
反射的实例应用:
在泛型为Integer的ArrayList中存储一个String类型的对象:
import java.lang.reflect.Method; import java.util.ArrayList; public class Main { public static void main(String[] args) throws Exception { ArrayList<Integer> list = new ArrayList<Integer>(); //list.add("asdf"); Method method = list.getClass().getMethod("add", Object.class); method.invoke(list, "Java反射机制实例。"); System.out.println(list.get(0)); } }
数组:
import java.lang.reflect.Array; public class Main { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5 }; Class<?> demo = temp.getClass().getComponentType(); //System.out.println(temp.getClass().getName()); System.out.println("数组类型: " + demo.getName()); System.out.println("数组长度 " + Array.getLength(temp)); System.out.println("数组的第一个元素: " + Array.get(temp, 0)); Array.set(temp, 0, 100); System.out.println("修改之后数组第一个元素为: " + Array.get(temp, 0)); } }
import java.lang.reflect.Array; public class Main { public static void main(String[] args) throws Exception { int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int[] newTemp = (int[]) arrayInc(temp, 15); print(newTemp); String[] atr = { "a", "b", "c" }; String[] str1 = (String[]) arrayInc(atr, 8); print(str1); } // 修改数组大小 public static Object arrayInc(Object obj, int len) { Class<?> arr = obj.getClass().getComponentType(); Object newArr = Array.newInstance(arr, len); int co = Array.getLength(obj); System.arraycopy(obj, 0, newArr, 0, co); return newArr; } // 打印 public static void print(Object obj) { Class<?> c = obj.getClass(); if (!c.isArray()) { return; } System.out.println("数组长度为: " + Array.getLength(obj)); for (int i = 0; i < Array.getLength(obj); i++) { System.out.print(Array.get(obj, i) + " "); } System.out.println(); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
数组长度为: 15 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 数组长度为: 8 a b c null null null null null
http://www.cnblogs.com/lzq198754/p/5780331.html
http://blog.csdn.net/liujiahan629629/article/details/18013523