黑马程序员——反射

------- android培训java培训、期待与您交流! ----------

Class类:
每一个java类都有一份字节码,每一份字节码都能映射一个Class的实例对象。

Class对象的获得方法:
1,类名.class:

Class cls1 = Date.class;

2,对象.getClass:

Person p1 = new Person();
p1.getClass();

3,Class.forName("类名"):

Class.forName("java.util.Date");//静态方法,返回字节码对象

Class.forName()的作用:
返回字节码,如果该类已经加载过,则从jvm中直接找到并返回。如果没有被加载过,则用类加载器去加载,将加载进来的字节码放到虚拟机中。

9个预定义的Class实例对象:8个基本类型对象.class+void.class;

isPrimitive()方法,判断是否是基本类型。

System.out.println(int.class == Integer.class);//*int与Integer不是同一个字节码。返回false
System.out.println(int.class == Integer.TYPE);Integer.TYPE返回其基本类型的字节码。返回true
System.out.println(int[].class.isPrimitive());//基本类型的数组并不是基本类型。
System.out.println(int[].class.isArray());//判断是否是数组,用isArray()方法。

总之,只要是在源程序中出现的类型,都有各自的Class实例对象,,例如,int[],void...

 

反射:就是把java类中的各个成分解析成相应的java类。


Constructor类:

Constructor[] constructor = Class.forName("java.lang.String").getConstructors();//获得所有的
Constructor constructor1 = String.class.getConstructor(StringBuffer.class,int.class);//返回参数为(StringBuffer sb,int i)的String类型的构造方法类。
String str2 = (String)constructor1.newInstance(new StringBuffer("abc"));


Field:

class ReflectPoint{
	private int x;
	public int y;
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "itcast";

	public ReflectPoint(int x, int y){
		this.x = x;
		this.y = y;
	}
}

ReflectPotin pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的没有具体的值,它不是对象身上的变量,而是类上的,要用它去取某个对象身上的值。
fieldY.get(pt1);//此时返回5。

//Field fieldX = pt1.getClass().getField("x");
//fieldX.get(pt1);//此时会产生NoSuchFieldException异常,证明private成员并不可见,不能直接对其进行操作。
Field fieldX = fieldX.getDeclaredField("x");//如果使用此方法,无论是否private,都可以取到。
fieldX.get(pt1);//但是取到此变量之后在读取对象值的过程中仍然会出现异常无法读取。
fieldX.setAccessible(true);//设置此变量可以被操作:暴力反射。

//将实例中所有字符串类型字段中的"b"替换成"a"
public static void changeStringValue(Object obj){
	Field[] fields = pt1.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:

String str = "abc";
Method methodCharAt = String.class.getMethod("charAt", int.class);

String value = (String)methodCharAt.invoke(str, 1);//*如果是静态方法,则第一个参数为null
System.out.println(value);//获得索引为1的字符,b


数组的反射:相同类型和相同维度的数组字节码对象是相同的。

int[] a1 = new int[3];
int[] a2 = new int[4];
int[] a3 = new int[2][3];
String[] a4 = new String[4];

System.out.println(a1.getClass() == a2.getClass());//上面4个对象的字节码中,只有a1与a2是相同的。


获得父类对象:getSuperclass

System.out.println(a1.getClass().getSuperclass().getName);//为java.lang.Object

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值