什么是java反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制API
java.lang.Class;反射机制使用
定义一个User类
package com.review.reflect; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void print(){ System.out.println(toString()); } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
package com.review.reflect; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { try { Class<?> u = Class.forName("com.review.reflect.User"); //创建对象实例 User user = (User) u.newInstance(); user.print(); //获取属性 Field fs[]=u.getDeclaredFields(); for (int i = 0; i < fs.length; i++) { System.out.println(fs[i]); } //获取方法 Method[] method=u.getDeclaredMethods(); for (int i = 0; i < method.length; i++) { System.out.println(method[i]); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } }在上面的例子中,演示了如何获取java对象,如何查看其属性跟方法,我们可以发现,通过反射java对象的私有变量我们也可以获取到,那么我们可以对其进行操作吗,来看个例子
package com.review.reflect; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { try { Class<?> u = Class.forName("com.review.reflect.User"); //创建对象实例 User user = (User) u.newInstance(); user.print(); //获取特定属性值 Field field=u.getDeclaredField("id"); // field.setAccessible(true); field.set(user, 10); user.print(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } }显示结果
User [id=0, name=null] java.lang.IllegalAccessException: Class com.review.reflect.Test can not access a member of class com.review.reflect.User with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261) at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253) at java.lang.reflect.Field.set(Field.java:738) at com.review.reflect.Test.main(Test.java:17)当我们将代码中
// field.setAccessible(true);注释取消,结果
User [id=0, name=null] User [id=10, name=null]说明通过反射是可以操纵java对性的私有变量的,这说明反射相对而言具有一定的风险性。
上面的例子中通过反射获取java对象及其属性跟方法并可进行了修改操作,其实反射的功能不仅仅如此,还可以获取方法返回类型、参数类型等,在这里就不一一叙说,大家可以参看API。
反射机制的优缺点
优点:
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能 。
缺点:
(1)使用反射的性能较低 。
(2)使用反射相对来说不安全。
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性。