J2SE(十二)Java之反射

什么是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)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性。


你可能感兴趣的:(J2SE)