JAVA反射技术(一)

一、反射的基础---Class

     Class是所有java类的一个总称,就好像各式各样的人都可以用Person来称呼,每一个类被加载之后都会在内存中生存一个Class对象,这个对象我们通常称之为字节码,而我们通过调用一个类创造的对象其实都是字节码搞出来的,一个类只会产生一份字节码。

     那么我们怎么获得一个类的Class呢?有三种方式:

        1.调用某个类的class属性  

        2.使用Class的forName()静态方法  

        3.调用某个对象的getClass()方法。

 

     下面我们通过一个实例来展示下上面两点:

ClassDemo1.java

 

 

package com.lyl.exercise;

public class ClassDemo1 {
	public static void main(String[] args) throws ClassNotFoundException{
		String str="iteye";
		Class cl1=String.class;
		Class cl2=str.getClass();
		Class cl3=Class.forName("java.lang.String");
		System.out.println("str对象与String是同一份字节码吗?"+(cl1==cl2));
		System.out.println("通过Class.forName()获得的字节码与String.class一样吗?"+(cl1==cl3));
	}
}

 

 

     通过查看JDK文档,我们可以发现,Class有许多方法,通过这些方法我们可以得到java类的相关信息,Constructor,Method,Field等,具体的大家可以参考JDK文档。

 

 

二、反射的应用

     那么什么是反射呢?曾经有人说过,反射就是把java类中的各种成分映射成相应的java类。为什么呢?从上一个讲解中大家是否发现,通过Class我们可以解析出一个java类的各种成分,他们返回的也是一个类,所以这句话还是很有道理的。

     下面让我们来看看反射的一些应用:

 

     1.使用反射生成对象

     通过反射来生成对象有两种方式:

        a.使用Class对象的newInstance()方法

        b.使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建Class对              应类的实例。

 

    实例: ClassDemo3.java

 

package com.lyl.exercise;

import java.lang.reflect.Constructor;

public class ClassDemo3 {
	public static void main(String[] args) throws Exception{
		//使用Class对象的newInstance()方法
		String str=(String)Class.forName("java.lang.String").newInstance();
		//使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建Class对应类的实例。
		Constructor constructor=String.class.getConstructor(StringBuffer.class);
		String str2=(String)constructor.newInstance(new StringBuffer("abc"));
	}
}

 

 

     2.成员变量的反射

 

     直接上实例大家看看:

 

ReflectDemo1.java

 

 

package com.lyl.exercise;

import java.lang.reflect.Field;

public class ReflectDemo1 {
	public static void main(String[] args) throws Exception {
		ReflectHelper rh=new ReflectHelper("iteye", "javaeye");
		Field fieldb=rh.getClass().getField("b");
		//fieldb只是类的字段,不是对象的,所以要想获得对象上的值,要使用get()方法
		System.out.println(fieldb.get(rh));
		//如果我们使用上面方法来访问a的值呢?抛出java.lang.NoSuchFieldException
		/*Field fielda=rh.getClass().getField("a");
		System.out.println(fieldb.get(rh));
		因为a是私有成员变量
		*/
		//我们可以通过暴力反射来获取它的值
		Field fielda=rh.getClass().getDeclaredField("a");
		//设置为可以访问
		fielda.setAccessible(true);
		System.out.println(fielda.get(rh));
	}
}

 

 

    ReflectHelper.java

 

package com.lyl.exercise;

public class ReflectHelper {
	private String a;
	public String b;
	public ReflectHelper(String a,String b){
		this.a=a;
		this.b=b;
	}
}

 

    如果将上面的搞懂,那么我们不妨来做一道经典的题目:将一个类中所有String类型的成员变量,其中含有的‘a’替换为‘b’。

    这个题目很明显通过反射可以轻易的完成,大家不妨来看看。

 

package com.lyl.exercise;

import java.lang.reflect.Field;

public class ReflectDemo2 {
	public static void main(String[] args) throws Exception {
		ReflectHelper rh=new ReflectHelper("abc", "basketball");
		changeStringValue(rh);
		System.out.println(rh);
	}

	private static void changeStringValue(Object object) throws Exception{
		Field[] fields=object.getClass().getFields();
		for(Field field:fields){
			if(field.getType()==String.class){
				String oldValue=(String)field.get(object);
				String newValue=oldValue.replace('a','b');
				//将object的String类型的变量替换为newValue
				field.set(object, newValue);
			}
		}
	}
}

 

   这样就搞定了,是不是很简单?

 

                                                                                                                               未完,待续。。。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值