什么是java反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射机制API
java.lang.Class;java.lang.reflect.Constructor; java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
反射机制使用
定义一个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)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性。