黑马程序员---初识反射,Class,Constructor,Field



------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流!  ----------

1、反射就是把java类中的各种成分映射成相应的java类
     要认识反射,首先要知道Class类,这个和class关键字不同,它是一个类,描述java类字节码文件的类。

2、获取该类对象的方法有三个:类名.class
                                                 new Date().getClass();
                                                 Class.forName("完整的类名-包名加类名");

<span style="font-size:14px;">                String str = "abc";
		Class<String> cls1 = (Class<String>) str.getClass();
		Class cls2 = String.class;
		Class cls3 = Class.forName("java.lang.String");</span>

        这三个Class对象表示的都是同一个字节码文件,可以使用==来判断一下他们是否指向同一个对象:

<span style="font-size:14px;">                System.out.println(cls1==cls2);
		System.out.println(cls1==cls3);</span>

        打印输出的结果都是:true,true,表示这三个方法获取的Class对象都是指向同一个。

        在java中有九个预定义的 Class 对象,他们是八个基本数据类型和void对应的.class字节码文件,即int.class,char.class等。

        他们还可以使用他们的包装类引用包装类中的静态成员变量TYPE,例如:Boolean.TYPE, Character.TYPE。

3、Class类中的方法boolean isPrimitive()可以判定指定的Class对象是不是基本类型,只有是上面的9种Class对象才返回真。

4、Class类中的Constructor<?> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它表示此 Class

        对象所表示的类的指定公共构造方法。

        例如:

<span style="font-size:14px;">     Constructor cons = String.class.getConstructor(StringBuffer.class);</span>

        这个就是获取String类中参数是StringBuffer类型的构造方法。

       如果要获取全部的构造方法可以使用Constructor<?>[] getConstructors(),它返回的是一个Constructor数组

5、使用Constructor类中的方法newInstance()可以创建相对应的类对象,但是在传参数时注意要和getConstructor()方法

      中的参数类型相对应,例如:

<span style="font-size:14px;">    String str = (String)cons.newInstance(new StringBuffer("abc"));</span>

      同时要注意的是要对创建的对象进行类型转换,因为java不能识别你创建的对象到底是什么类型的。

6、Field 类,Class类中的getField方法可以获取指定Class对象的Field对象,该对象反映此Class 对象表示的类的成员变量,但

     是  这个方法只能获取被public修饰的成员变量,如果要获取私有的成员变量要使用getDeclaredField方法,这个方法只要是在     类中声明过的都能获取到。

    类ReflectPoint:

<span style="font-size:14px;">public class ReflectPoint {
	private int x;
	public int y;</span>
<span style="font-size:14px;">      public String str1 = "abc";</span>
<span style="font-size:14px;">      public String str1 = "abc";
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	
}</span>

  获取Field对象的方法:

<span style="font-size:14px;">ReflectPoint rp1 = new ReflectPoint(3, 5);
		//获取ReflectPoint类中的xy成员变量,由于X是私有的,只能使用getDeclaredField方法,只要是在类中声明的都可以获取
		//其中fx,fy代表的不是对象rp1对象中xy的值,而是一个变量,要获取rp1对象中xy的值使用get(Object)方法,
		//但是fx要先使用setAccessible将fx设置为true,才能获取rp1对象中x的值
		Field fx = rp1.getClass().getDeclaredField("x");
		Field fx = rp1.getClass().getField("x");
		Field fy = rp1.getClass().getField("y");
		fx.setAccessible(true);</span>

      上面的Field fx = rp1.getClass().getField("x");这一行就会报

        Exception in thread "main" java.lang.NoSuchFieldException: x异常

这个时候就可以使用Field中的方法获取类ReflectPoint中对象rp1 x,y想对应的值,要注意的是fx,fy并不表示对象rp1中x,y的值。但是在获取rp1对象的X的值要先调用Field父类AccessibleObject中的setAccessible方法,将fx对象的accessible值设置为true,这样就可以使用Object get(Object obj) 方法获取rp1对象中x,y的值,注意这个方法返回的是Object对象,

如果要将返回的值赋给一个int型变量的话,要做转型。例如:

<span style="font-size:14px;">                fx.setAccessible(true);
		int i = (Integer)fx.get(rp1);
		System.out.println(i);
		System.out.println(fx.get(rp1));
		System.out.println(fy.get(rp1));</span>

7、使用反射将类ReflectPoint中的String类型成员变量中的字符o全部替换成b

private static void changeChar(Object obj) throws Exception, IllegalAccessException {
		// 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('o', 'b');
				field.set(obj, newValue);
			}
		}
	}

调用方法,打印rp1对象中str1和str2的只

changeChar(rp1);
		
		System.out.println(rp1);


输出结果

abc:hellb wbrld








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值