Java反射学习

一、Class类

  • 众多的人属于同一类事物,我们可以用Person类来表示。Java中的各个Java类也属于同一类事物,描述这类事物的Java类名就是Class。
  • Person类的实例对象是一个个具体的人,如张三;Class类的实例对象则是各个类在内存中的字节码。(一个类被类加载器加载到内存中,占用一片存储空间,这片空间中的内容就是类的字节码)
  • 获得各个字节码对应的实例对象   1.类名.class  2.对象.getClass()  3.Class.forName("类名")

二、反射

反射就是把Java类中的各种成分映射成相应的java类。成员变量、方法、构造方法等信息用Field类、Method、Constructor表示等。

三、构造方法的反射——Constructor类

import java.lang.reflect.Constructor;

public class ConstructorDemo {
	/**
	 * Constructor类代表某个类中的一个构造方法
	 * 1.得到某个类所有的构造方法
	 *   Constructor constructors[] = Class.forName("java.lang.String").getConstructors();
	 * 2.得到某一个构造方法
	 *   Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
	 * 3.创建实例对象
	 * 	  通常方式:String str = new String(new StringBuffer("abc"));
	 *   反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));
	 */
	public static void main(String[] args)throws Exception {
		//new String(new StringBuffer("abc"));
		Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
		String newString = (String)constructor1.newInstance(new StringBuffer("abc"));
		System.out.println(newString);
	}
}

四、成员变量的反射——Field类

首先创建一个ReflectPoint类,含有一个私有成员x和公有成员y。

public class ReflectPoint {
	private int x;
	public int y;
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}	
}
import java.lang.reflect.Field;

public class FieldDemo {
	/**
	 * Field类代表某个类中的一个成员变量
	 */
	public static void main(String[] args)throws Exception {
		ReflectPoint rp1 = new ReflectPoint(1, 2);
		ReflectPoint rp2 = new ReflectPoint(3, 4);
		//因为x是私有的
		Field fieldX = rp1.getClass().getDeclaredField("x");
		fieldX.setAccessible(true);
		System.out.println("rp1.x=" + fieldX.get(rp1));
		System.out.println("rp2.x=" + fieldX.get(rp2));
		//y是公有的
		Field fieldY = rp1.getClass().getField("y");
		//fieldY的值是多少?是2?错!fieldY不是某一个对象身上的变量,而是该类上的,要用它去取某个对象上对应的值
		System.out.println("rp1.y=" + fieldY.get(rp1));
		System.out.println("rp2.y=" + fieldY.get(rp2));
	}

}

例题:将任意一个对象中的所有String类型的成员变量所对应的字符串中的"b"改为"a"。

public class ReflectPoint {
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "itcast";
	@Override
	public String toString() {
		return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3=" + str3 + "]";
	}
}
import java.lang.reflect.Field;

public class ClassDemo {

	public static void main(String[] args) throws Exception {
		ReflectPoint pt1 = new ReflectPoint(1, 2);
		changeStringValue(pt1);
		System.out.println(pt1.toString());
	}

	private static void changeStringValue(Object obj) throws Exception {
		// TODO Auto-generated method stub
		Field[] fields = obj.getClass().getFields();
		for(Field field : fields){
			if(field.getType() == String.class){
				String oldValue = (String)field.get(obj);
				String newValue = oldValue.replace('b', 'a');
				field.set(obj, newValue);
			}
		}
	}
}

五、成员方法的反射——Method类

import java.lang.reflect.Method;

public class MethodDemo {
	/**
	 * Method类代表某个类中的一个成员方法
	 * 1.得到类中的某一个成员方法
	 *   Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
	 * 2.调用方法
	 *   通用方式:System.out.println(str.charAt(1));
	 *   反射方式:System.out.println(charAt.invoke(str,1));
	 */
	public static void main(String[] args)throws Exception {
		// TODO Auto-generated method stub
		Method methodcharAt = String.class.getMethod("charAt", int.class);
		System.out.println(methodcharAt.invoke(new String("abc"), 1));
	}

}

当参数是一个数组时,jdk1.4会把这一个数组参数当作数组长度个参数。例如,

main(new String[]{"aaa","bbb","ccc"}),实际上是一个字符串数组作为参数,但编译器会当作是三个字符串参数。

应该写成main(new object[]{new String[]{"aaa","bbb","ccc"}})

六、数组的反射

  • 具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
  • 基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值