java反射总结

一:反射机制
   在程序的运行时期,通过Class类的内部结构,并可实例化类,并修改值域,调用方法等。
二:反射包含的内容
   2.1 所有的类的对象都是Class的实例
   2.2 通过对象获得对应的包,类,以及类加载器
  包:class.getClass().getPackage();
  类:class.getClass().getName();
  类加载器:class.getClass().getClassLoader();
   2.3 获得java对象的三种方式(class代表需要实例的对象)
     2.3.1 class = Class.forName("classpath");//反射
  2.3.2 class = new class();
  2.3.3 classname = classname.class;
   2.4 反射得到对象代码示例
     Class<?> cla = null;
  Person per = null;
  cla = Class.forName("personpath");//注意这里可能抛出ClassNotFoundException的异常
  per = (Person)cla.newInstance();//注意这里可能抛出InstantiationException和IllegalAccessException异常
  per.setName("jack");
  
  在这里需要注意,当person中有一个有参的构造函数时,一定要保证这个类里面有一个无参的构造函数
  class.froName调用的是无参的构造函数
   2.5 通过反射的构造方法获得对象
     Class<?> cla = null;
  Person per = null;
  cla = Class.forName("personpath");//注意这里可能抛出ClassNotFoundException的异常
  这里反射处对象不同:
     Constructor<?> cons[]=demo.getConstructors();
   person = (Person)cons[i].newInstace();
      person1 = (Person)cons[i].newInstace(arrayMap);
   2.6 通过反射获得对象的实现接口
   Class<?> cla = null;
   cla = Class.forName("classpath");
   Class<?> cls[] = cla.getInterfaces();//获得类继承的所有的接口
   for(int i=0;i<cls.length;i++)
       cls[i].getName();
   2.7 通过反射获得对象的字段
      Field[] fields = cla.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
int mod = field.getModifiers();
Class<?> types = field.getType();
System.out.println(Modifier.toString(mod)+" "+types.getName()+" "+field.getName());
}
   2.8 通过反射调用方法
       People people = (People)cla.newInstance();
Method method = cla.getMethod("setName", String.class);//获得setName方法,且setName的参数是String类型
method.invoke(people, "java ck");//调用people的setName方法,传递java ck参数到setName方法中
System.out.println(people);
   2.9 通过反射来修改类的值域
      try{
System.out.println("--------测试修改域的值----------");
Field fx = cla.getDeclaredField("age");
People people = (People)cla.newInstance();
System.out.println("修改前age值:"+fx.get(people));
fx.set(people, 20);
System.out.println("修改后age值:"+fx.get(people));
System.out.println(people.age);
}catch(Exception e){
e.printStackTrace();
}

   2.10 实例代码参看PeopleReflectDemon和People类

  接口China和English

public interface China {
	public static final String name="Rollen";
    public static  int age=20;
    public void sayChina();
    public void sayHello(String name, int age);
}
public interface English {

}

           People类

public class People implements China,English{

	private int id;
	private String name;
	public static  int age;
	public final String address="1";
	
	public People(){}
	public People(String name){
		this.name = name;
	}
	public People(int id,String name){
		this.id = id;
		this.name = name;
	}
	
	@Override
	public void sayChina() {
		System.out.println("说普通话");
	}

	@Override
	public void sayHello(String name, int age) {
		System.out.println(name+" "+age);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	private int getCount(int a){
		return 2;
	}
	
	public String getString(int a,String b){
		return "abc";
	}
	
	public String toString(){
		return "id:"+id+" name:"+name+" age:"+age;
	}
}
PeopleReflectDemon类

public class PeopleReflectDemon {
	static Class cla = null;
	static{
		try{
		cla = Class.forName("flymoke.reflect.People");
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}
	}
	
	public PeopleReflectDemon() throws Exception{
		System.out.println("people类");
		this.getExtends();
		this.getInterface();
		this.getConstructors();
		this.getField();
		this.getMethod();
		this.getPeople();
		this.invokMethods();
		this.setFields();
	}
	
	public void getInterface(){
		System.out.println("--------获得People的所有接口----------");
		Class<?>[] inter = cla.getInterfaces();
		for (int i = 0; i < inter.length; i++) {
			System.out.println(inter[i].getName());
		}
	}
	
	public void getExtends(){
		System.out.println("--------获得People的所有父类----------");
		Class<?> ext = cla.getSuperclass();
		System.out.println(ext);
	}
	/**
	 * 获得People的构造方法
	 */
	public Constructor<?>[] getConstructors(){
		System.out.println("--------获得People的所有构造方法----------");
		Constructor<?>[] con = cla.getConstructors();
		for (int i = 0; i < con.length; i++) {
			System.out.println(con[i]);
		}
		return con;
	}
	
	public void getField(){
		System.out.println("--------获得People的所有字段定义----------");
		Field[] fields = cla.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			int mod = field.getModifiers();
			Class<?> types = field.getType();
			System.out.println(Modifier.toString(mod)+" "+types.getName()+" "+field.getName());
		}
	}
	
	public Method[] getMethod(){
		System.out.println("--------获得People的所有方法----------");
		Method[] methods = cla.getDeclaredMethods();
		StringBuffer methodDefine = new StringBuffer();
		for (int i = 0; i < methods.length; i++) {
			Method method = methods[i];
			int mod = method.getModifiers();
			Class<?> returnType = method.getReturnType();
			 methodDefine.append(Modifier.toString(mod)+" "+returnType+" "+method.getName()+"(");
			Class<?> para[]=methods[i].getParameterTypes();
			for(int j=0;j<para.length;++j){
                methodDefine.append(para[j].getName()+" "+"arg"+j);
                if(j<para.length-1){
                	methodDefine.append(",");
                }
            }
			methodDefine.append(");\n");
		}
		System.out.println(methodDefine.toString());
		return methods;
	}
	
	public void getPeople() throws IllegalArgumentException, InvocationTargetException{
		System.out.println("--------获得People----------");
		try {
			People p1 = (People) cla.newInstance();
			System.out.println("p1"+p1);
			//通过构造方法获得类
			Constructor<?>[] con = this.getConstructors();
			
				People p2 = (People) con[2].newInstance();
				People p3 = (People) con[0].newInstance(1,"jack");
				People p4 = (People) con[1].newInstance("jack");
				System.out.println("p2:"+p2);
				System.out.println("p3:"+p3);
				System.out.println("p4:"+p4);
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void invokMethods() throws Exception{
		System.out.println("--------测试调用方法----------");
		People people = (People)cla.newInstance();
		Method method = cla.getMethod("setName", String.class);
		method.invoke(people, "java ck");
		System.out.println(people);
	}
	
	public void setFields(){
		try{
			System.out.println("--------测试修改域的值----------");
			Field fx = cla.getDeclaredField("age");
			People people = (People)cla.newInstance();
			System.out.println("修改前age值:"+fx.get(people));
			fx.set(people, 20);
			System.out.println("修改后age值:"+fx.get(people));
			System.out.println(people.age);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public static void main(String[] args) throws Exception {
		new PeopleReflectDemon();
	}
}


三:在实际中哪里用到了java的反射
   3.1 jdbc连接数据库
             通过jdbc连接数据库的代码如下:
        Class.forName("com.mysql.jdbc.Driver");
        DriverManager.getConnection("jdbc:mysql://192.168.1.200:3306/test", "root", "root");
            第一步生成一个mysql提供的Driver实例,因为Driver是实现了sql的DrvierManager接口,所以第二步其实是调用了通过反射得到的
         mysql的Driver包连接数据库。
   3.2 spring中的bean配置,也是通过java的反射实现的,这里有一个动态代理的概念,大家可以看spring的源码了解反射在spring中的
    使用。
   3.3 struts和hibernate中也同样的使用到了反射
四:反射同工厂模式结合
   首先我们来看一个简单工厂(转载自 http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
 
  interface fruit{
    public abstract void eat();
}
 
class Apple implements fruit{
    public void eat(){
        System.out.println("Apple");
    }
}
 
class Orange implements fruit{
    public void eat(){
        System.out.println("Orange");
    }
}
 
// 构造工厂类
// 也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class Factory{
    public static fruit getInstance(String fruitName){
        fruit f=null;
        if("Apple".equals(fruitName)){
            f=new Apple();
        }
        if("Orange".equals(fruitName)){
            f=new Orange();
        }
        return f;
    }
}
class hello{
    public static void main(String[] a){
        fruit f=Factory.getInstance("Orange");
        f.eat();
    }
 
}    


在这个工厂中,通过字符串来生成不同的产品(如if("Apple".equals(fruitName)){ f=new Apple();}),这样做的不好之处就是违反了
开闭的原则,因为如果要是新增加一个产品,那么需要修改工厂类,添加一个新的判断生成产品的代码。

下面来看下使用发射后的工厂模式


interface fruit{
    public abstract void eat();
}
 
class Apple implements fruit{
    public void eat(){
        System.out.println("Apple");
    }
}
 
class Orange implements fruit{
    public void eat(){
        System.out.println("Orange");
    }
}
 
class Factory{
    public static fruit getInstance(String ClassName){
        fruit f=null;
        try{
            f=(fruit)Class.forName(ClassName).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}
class hello{
    public static void main(String[] a){
        fruit f=Factory.getInstance("Reflect.Apple");
        if(f!=null){
            f.eat();
        }
    }
}


传入不同的类路径,再通过工厂的反射生成想要的产品,这样,即使新增加了产品,但只要在使用的时候传入新增加的产品类路径,同样
可以产生新增加的产品,这样就不用去修改工厂的具体实现,这样就符合了开闭的原则
五:反射的优缺点
  5.1 反射的优点:
      反射可以在运行期间创建实例
  5.2 反射的缺点:
   5.2.1 反射的效率比一般的低,一般是10~20倍,且java版本越低,反射的效率越低
   5.2.2 反射的代码的可读性差,一般都不是很规范,大家可以参看前面的PeopleReflectDemon
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值