Java 反射机制的个人理解

原文出处:https://blog.csdn.net/sinat_38259539/article/details/71799078

java反射机制的定义:

在java反射机制是在运行状态中,对于任意一个类,都能知道他的属性和方法。对于任意一个对象,都能够调用他的任意一个方法,这种动态获取的信息以及动态调用对象的方法的功能,称作为java语言的反射机制。

动态:指的就是非编译时处理,运行时处理。

Java类的加载顺序:


     

每一个Java类在加载进内存时一定会产生一个class对象,在里面有关于类的信息

这时候就需要去了解一下Class类:

Class类的实例表示正在运行中的Java类或者接口。

Class没有公共构造方法。Class对象是在jvm加载类的时候自动创建的。、

Jvm中运行的每一个Java类都对应一个Class类的实例。


/** 
 * 获取Class对象的三种方式 
 * 1 Object ——> getClass(); 
 * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性 
 * 3 通过Class类的静态方法:forName(String  className)(常用) 
 * 
 */  
public class Fanshe {  
    public static void main(String[] args) {  
        //第一种方式获取Class对象    
        Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。  
        Class stuClass = stu1.getClass();//获取Class对象  
        System.out.println(stuClass.getName());  
          
        //第二种方式获取Class对象  
        Class stuClass2 = Student.class;  
        System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个  
          
        //第三种方式获取Class对象  
        try {  
            Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名  
            System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象  
        } catch (ClassNotFoundException e) {  
            e.printStackTrace();  
        }  
          
    }  
}

一般都是用第三种方法,因为它对于原来的Java类的依赖最少,不需要导包

Java的反射一般用在运行时读取配置文件:

public class Student2 {  
    public void show2(){  
        System.out.println("is show2()");  
    }  
}  
className = cn.fanshe.Student  
methodName = show  

import java.io.FileNotFoundException;  
import java.io.FileReader;  
import java.io.IOException;  
import java.lang.reflect.Method;  
import java.util.Properties;  
  
/* 
 * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改 
 * 我们只需要将新类发送给客户端,并修改配置文件即可 
 */  
public class Demo {  
    public static void main(String[] args) throws Exception {  
        //通过反射获取Class对象  
        Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"  
        //2获取show()方法  
        Method m = stuClass.getMethod(getValue("methodName"));//show  
        //3.调用show()方法  
        m.invoke(stuClass.getConstructor().newInstance());  
          
    }  
      
    //此方法接收一个key,在配置文件中获取相应的value  
    public static String getValue(String key) throws IOException{  
        Properties pro = new Properties();//获取配置文件的对象  
        FileReader in = new FileReader("pro.txt");//获取输入流  
        pro.load(in);//将流加载到配置文件对象中  
        in.close();  
        return pro.getProperty(key);//返回根据key获取的value值  
    }  
}

自己写的一个

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Properties;

public class TestReflect {

	public static void main(String[] args) {
		
		try {
			Class cls = Class.forName(getClassName("ClassName"));
			Method m = cls.getMethod(getClassName("MethodName"));
			Constructor[] cons = cls.getDeclaredConstructors();
			for(Constructor con : cons){
				System.out.println(con);
				m.invoke(con.newInstance("anna","19"));
			}
			Constructor con = cls.getConstructor(String.class,String.class);
			con.newInstance("anna","19");
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	private static String getClassName(String key) {
		// TODO Auto-generated method stub
		try {
			Properties pro = new Properties();
			FileInputStream fis = new FileInputStream("D:\\workspace\\Test\\src\\day01\\config.properties");
			pro.load(fis);
			fis.close();
			String classname = pro.getProperty(key);
/*			String teachername = pro.getProperty("TeacherName");
			String teacherage = pro.getProperty("TeacherAge");
			String classmethod = pro.getProperty("ClassMethod");
			HashMap<String, String> map = new HashMap<String, String>();
			map.put(arg0, arg1);*/
			
			return classname;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
}

class Teacher{

	public String name;

	public String age;
	
	public Teacher(String name, String age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public void print(){
		System.out.println("this is print method");
		System.out.println("name = "+name+" age = "+age);
	}
}

此时通过反射读取配置文件内容,运行方法。

Java反射还有一个比较普遍的使用的地方:Spring中BeanUtils.copy 方法:

之前做过一个项目,在VO与PO的属性赋值上大量使用了get/set方法;代码冗余

使用copy方法简单快捷,不过因为反射机制效率较低,所以最好少使用。

Java反射机制其实破坏了封装性

setAccess(True)这个方法,可以使本来私有的,无法访问的属性/方法变成可以访问的


技术都是有正反两面的,看需求,看使用者


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看rEADME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值