Java高级特性–反射

 Class 表示类的类,描述一类事物,规定类应该有什么属性,不应该有什么属性。但是不要求有什么属性。
 2.Class表示字节码的抽象,不知直接去构造(new Class())
 3.Person p1=new Person(),虚拟机编译时,首先需要加载Person.class文件到内存中
 4.Class c=Person.class,表示内存中实实在在的一堆字节码,p1代表那一堆字节码生成的对象。Class就表示字节码的抽象,c如上所述,表示的是字节码的引用
 5.Field:代表类的成员变量
 6.Constructor:代表类的构造方法
 7.Method:代表类的方法

package reflectclass;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class StudentTest {
	/**
	 * @param args
	 * @throws Exception 
	 * @throws InstantiationException 
	 */
 
	public Object create(Object obj) throws Exception {
		Class<?> classType=obj.getClass();
		System.out.println("the class type:"+classType.getName());
		Object student=classType.newInstance();
		student=classType.getConstructor(null).newInstance(null);
//		student=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
		Field fields[]=classType.getDeclaredFields();
		for(Field f:fields) {
			Field field=f;
			String fieldName=field.getName();
			String firstName=fieldName.substring(0,1).toUpperCase();
			String getMethodName="get"+firstName+fieldName.substring(1);
			String setMethodName="set"+firstName+fieldName.substring(1);
			Method getMethod=classType.getMethod(getMethodName, new Class[]{});
			Method setMethod=classType.getMethod(setMethodName, new Class[]{field.getType()});
			Object value=getMethod.invoke(obj, new Object[]{});
			System.out.println("value:"+value);
			setMethod.invoke(student, new Object[]{value});
 
		}
 
		return student;
	}
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Student s=new Student("student",23);
		s.setId(1);
		StudentTest st=new StudentTest();
		st.create(s);
	}
 
}


 StudengTest两个重点的地方:
 第一个地方:通过默认构造器获得classType对象的过程,下面一个有参数的构造方法,但是参数内容为空。通常生成默认构造方法的对象,可直接class.newInstance()
 第二个地方:获得Method对象,获得过程是类似bean的方法,通过改变变量的大写字母手写,然后加上set、get,以得到方法名。
 再来看一个通过有参构造函数构造一个类的对象的:

package reflectclass;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class StudentTest1 {
	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
		// TODO Auto-generated method stub
		Class classType=Class.forName("reflectclass.Student");//要用类的全名:包含包名
		System.out.println("classtype:"+classType.getName());
		Constructor construct=classType.getConstructor(new Class[]{String.class,int.class});//获得有参构造函数
		construct=classType.getConstructor(String.class,int.class);//<1>
		Object obj=construct.newInstance(new Object[] {"jack",32});//通过有参构造函数构造student对象
		obj=construct.newInstance("jack",32);//<2>
		System.out.println(obj);
		System.out.println("通过方法的invoke获得方法值");
		Method getName=classType.getMethod("getName", null);
		Method getAge=classType.getMethod("getAge", null);
		String name=(String)getName.invoke(obj, null);
		int age=(Integer)getAge.invoke(obj, null);
		System.out.println("getname:"+name+"\t"+"getage:"+age);
	}
 
}

 注意代码中注释的地方:我们查看api可以知道,getConstructor(),newInstance(),他们的参数都是可变参数,可变参数实际上是一个数组,所以有两种写参数的方式:用数组和按个数写参数
 另一个需要注意的地方是用Class.forName()载入class文件的字节码,参数是类的全名,就是带上包名
 方法的invoke调用很简单,不过也要注意其参数:第一个参数是调用该函数的对象;二个参数是方法的参数,推荐用Class数组的形式。没有参数的方法直接用null。
 8.Class是反射的起源,如果想使用class,必须先产生一个Class Object,之后才能使用一系列的Reflect里的一些列方法。
 9.获得class的方式有一下几种:

		getClass():object.getClass();
		getSuperclass():object.getSuperclass();
		forName():Class.forName(String)	静态方法,使用方便,很常用
		.class:Class.class
		TYPE:Integer.TYPE	这个是运用原始包装类的TYPE方法

 10.reflect包中除了以上几个类以外,另Array类,他所有的方法都是静态的,可以通过类名调用。先看个例子

package reflectclass;
import java.lang.reflect.Array;
public class ArrayTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Class<?> classType=null;
		try {
			classType=Class.forName("java.lang.String");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Object array=Array.newInstance(classType, 10);
		Array.set(array, 5, "ArrayTest");
		System.out.println(Array.get(array, 5));
	}
 
}

 Array其他的方法查看API就行了,不一一举例
 以上就是反射的常用用法
把sutdent类也附带上,供大家参考

package reflectclass;
 
public class Student {
	private long id;
	private String name;
	private int age;
	public Student() {
 
	}
	public Student(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	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;
	}
	public String toString() {
		return "name:"+name+"\t"+"age:"+age;
	}
}

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Go back to top