java的反射机制

问题:java程序在运行时,对于一个java类,能否知道属性和方法;能否去调用它的任意方法? 答案是肯定的,就是使用java的反射机制。

一、什么是反射机制

       简解:Java可以加载一个运行时才得知名称的class,获得其完整结构。

二、哪里用到反射机制    

 

三、反射机制的优点与缺点
        为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念,
    静态编译:在编译时确定类型,绑定对象,即通过。
    动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。
    一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能 的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。
       它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它
    满足我们的要求。这类操作总是慢于只直接执行相同的操作。   

Java反射机制提供如下功能:

1、在运行时判断任意一个对象所属的类

2、在运行时构造任意一个类的对象

3、在运行时判段任意一个类所具有的成员变量和方法

4、在运行时调用任一个对象的方法

5、在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。

package lxf;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person() {
		// TODO Auto-generated constructor stub
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

/**
 * 使用反射机制来创建对象
 * 
 * @author lxf
 * @time 2014-4-8下午05:08:41
 * 
 */
public class CreateObject {

	/**
	 * Java的反射机制是指:反射就是把Java类中的各种成分映射成相应相应的Java类, 然后就可以获取这个类的所有信息
	 * 
	 * @throws Exception
	 */
	public static void createObj1() throws Exception {
		// 返回与带有给定字符串名的类或接口相关联的 Class 对象。
		// Class classType = Person.class;
		Class classType = Class.forName("lxf.Person");
		Object obj = classType.newInstance();
		System.out.println("使用反射反射机制创建出来的对象是否是Person类的对象:"
				+ (obj instanceof Person));
	}

	/**
	 * 创建带有构造参数的对象的时候我们需要使用另外一种方式即: 1.先获取操作类的Class对象即字节码文件
	 * 2.使用Class对象的getConstructor
	 * (parameterTypes)方法获取该对象的构造方法的对象,注意括号中可以带不等的可变参数,
	 * 3.使用构造方法对象的newInstance(initargs)方法就可以实例化一个对象 4.注意,使用这些方法都不可以访问被
	 * private修饰的方法,需要设置某些访问权限setAccessable()方法
	 * 
	 * @throws Exception
	 */
	public static void createObj2() throws Exception {
		@SuppressWarnings("rawtypes")
		Class classType = Person.class;

		@SuppressWarnings("unchecked")
		Constructor<Person> con = classType.getConstructor(String.class,
				int.class);
		Object obj = con.newInstance("lxf", 23);
		System.out.println("使用constructor对象的newInstance方法创建对象的信息:"
				+ ((Person) obj).getName());
	}

	/**
	 * 操作方法包括(private方法) 步骤: 1.首先获取要操作类的Class对象
	 * 2.然后通过Class对象的getMethod方法获取要操作的方法的Method对象(两个参数,第一个参数是方法名,第二个参数是参数类型)
	 * 3.调用Method的方法的invoke方法(两个参数,第一个参数是该方法属于的类对象,具体参数)
	 * 4.当方法被private修饰的时候,首先需要调用getDeclaredMethod()方法获取要操作的被private修饰的类。
	 * 在这里要注意这个getDeclaredMethod方法,它既可以用作获取普通方法的对象也可以用来操作private修饰的方法,
	 * 但是操作private修饰的方法的时候,必须使用这个方法,其它方法不可以。普通方法还可以使用getMethod方法,
	 * 且属性操作也是如此。另外,还需要设置访问权限setAccessable(true)才可以
	 * 
	 * @throws Exception
	 */
	public static void methodDo() throws Exception {
		Person p = new Person();
		Class classType = Person.class;
		Method method = classType.getMethod("setName", String.class);
		method.invoke(p, "ckl");
		System.out.println("使用反射操作SetName方法后,Person对象的name值是:" + p.getName());

		Method method2 = classType.getDeclaredMethod("test");
		method2.setAccessible(true);
		method2.invoke(p);
	}

	/**
	 * 操作字段
	 * 
	 * @throws Exception
	 */
	public static void FieldDo() throws Exception {
		Person p = new Person();
		Class classType = Person.class;
		Field field = classType.getDeclaredField("name");
		Field field2 = classType.getDeclaredField("age");
		field.setAccessible(true);
		field2.setAccessible(true);
		field.set(p, "lxf");
		field2.set(p, 23);
		System.out.println("使用反射机制操作被private修饰的对象字段后得到的属性值是:" + p.getName());
		System.out.println("使用反射机制操作被private修饰的对象字段后得到的属性值是:" + p.getAge());
	}

	public static void main(String[] args) throws Exception {
		new CreateObject().FieldDo();
	}

}

 

你可能感兴趣的:(java的反射机制)