JAVA学习之反射

一、概念

反射:反射就是把java类中的各种成分映射成一个个的Java对象

Class对象的由来是将class文件读入内存,并为之创建一个Class对象,同一个类只创建一个Class对象

二、程序的运行过程

classLoader将class文件load到内存中的code segment中,运行环境找到main方法开始执行,运行过程中会动态的加载其他的

class文件

三、classLoader的类加载机制

(1)并不是一次性的加载,而是需要的时候再加载(运行期间动态加载)
(2)static{}:静态语句块,只加载一次
(3){}:动态语句块,每次new新的对象会执行一次,等同于构造方法的语句
若想在eclipse中观察到类的具体加载过程,可以设置:

run as--> run configurations -->VM arguments 设置 -verbose:class

四、JDK中classLoader的分类

(1)bootstrap classLoader:最开始加载的,加载的是jdk核心的类
(2)extesion classLoader:加载jre/lib/ext里的类,像什么jar包里的类
(3)application classLoader:加载我们自己的类,或者是ClassLoader.getSystemClassLoader

(4)other classLoader:URLClassLoader........

五、JDK中classLoader的层次关系(不是继承)

bootstrap<---extesion<--application 
application中有指向extesion的引用,classLoader在load class时首先找上一层的loader是不是已经load过了
如果已经load了就不会再次load

安全性好:自己写的String.class永远没机会执行(破坏性的代码)

可以通过getParent()获得上一层的loader

六、反射使用方法

站在classLoader看code segment是一个一个Class对象
class里面有属性对象和方法对象
(1)加载类
Class.forName("");//把该类加载到内存,注意:是该类的全路径(包名+类名)
(2)创建实例对象
Class c = Class.forName("")  Object o =  c.newInstance();
(3)通过反射获取构造方法并使用
所有公有构造方法:Constructor [] conArray = c.getConstructors();
所有构造方法(私有,默认,受保护,公有)Constructor [] conArray = c.getDeclaredConstructors();
获取公有构造方法:Constructor con = c.getConstructor();
调用:Object o =  c.newInstance();
获取私有构造方法:Constructor con = c.getDeclaredConstructor("");//引号里是参数的类型
调用:con.Accessible(true);//暴力访问  Object o =  c.newInstance();
(4)获取成员变量并调用
所有公有的字段:Field [] fieldArray = c.getFields();
所有的字段:Field [] fieldArray = c.getDeclaredFields();
获取公有字段:Field f = c.getField("字段名");
调用:f.set(o,"刘德华");//第一个参数:对象   第二个参数:值
获取私有字段:Field f = c.getDeclaredField("字段名");
调用:f.setAccessible(true);  f.set(o,"1111");
(5)获取成员方法并调用
所有公有的方法:Method [] methodArray = c.getMethods();
所有的方法:Method [] methodArray = c.getDeclaredMethods();
获取公有方法:Method m = c.getMethod("方法名","参数类型"); 
调用:m.invoke(o,"刘德华");
获取私有方法:Method m = c.getDeclaredMethod("方法名","参数类型");如int.class,String.class.....
调用:m.setAccessible(true); m.invoke(o,"1111");
(6)反射main方法
Method method = c.getMethod("main", String [].class);
method.invoke(null, (Object)new String[]{"a","b","c"});

(7)通过反射运行配置文件内容

举例:

属性文件:

className = com.\u53CD\u5C04.Student
methodName = show

public class TestReflection {
	public static void main(String[] args) throws Exception{
		TestReflection t = new TestReflection();
		Class c = Class.forName(t.getValue("className"));
		Method method = c.getMethod(t.getValue("methodName"));
		method.invoke(c.newInstance());
		
		
		
		
	}
	
	public String getValue(String key) throws Exception{
		Properties pro = new Properties();
		InputStream in = this.getClass().getResourceAsStream("test.properties");//在同一包内
		pro.load(in);
		in.close();
		return pro.getProperty(key);
	}
}

class Student	{
	 public void show(){  
	        System.out.println("is show()");  
	    }  
	
}

七、好处和缺点

好处:反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。

          它允许程序创建和控制任何类的对象,无需提前硬编码目标类

缺点:性能上慢于直接代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值