• 类加载器与反射


    当程序使用类的时候,类会被加载到内存中。整个过程分三步:

    1.加载:将类文件加载到内存的堆中中,创建字节码文件对象。

    2.连接,验证文件内部结构是否正确。

       准备:为静态成员分配内存,并设置默认初始化值

        解析:将类的二进制数据的符号引用换为直接引用

    3.初始化

    类加载器组成:

     Bootstrap ClassLoader 根类加载器:负责java核心类的加载

     Extension ClassLoader 扩展类加载器:负责jre的扩展目录的jar包的加载

     System ClassLoader 系统类加载器:负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。

    反射是不通过对象直接调用类的一切属性和方法的方式。

    步骤:(1)获取class对象

       (2)通过class对象获取方法或属性

         (3) 执行方法,修改属性

    获取Class对象的三种方式 (1)Class c=Class.forName(路径);(2)对象.getClass (3)类名.class

    获取方法的方式(1)获取构造方法 getConstructor()(2)获取普通方法getMethod()(3)获取一切方法(包括私有修饰的)getDeclaredMethod(4)获得一切构造方法与获得一般方法类同,也是加上Declared修饰

    执行方法用invoke(),但若要执行私有方法,需要先将获得的私有方法setAccesible(true),才能执行。若修改私有成员变量也需要这样。

    获取成员变量的方法  getField()(获取私有的成员变量与获取私有方法的方式类似),修改成员变量方法:set()。

    下面是一个例子:

    public class Demo01 {
    	public static void main(String[] args) throws Exception {
    		ti5();
    	}
    //	ArrayList<Integer> list = new ArrayList<Integer>(); 
    //	这个泛型为Integer的ArrayList中存放一个String类型的对象
    	public static void ti1() throws Exception, Exception{
    		ArrayList<Integer> list = new ArrayList<Integer>(); 
    		Class c=list.getClass();
    		Method method=c.getMethod("add",Object.class);
    		method.invoke(list,"你好");
    		System.out.println(list);
    	}
    	//用反射去创建一个对象,有2种方式,尽量用代码去体现
    	public static void ti2() throws Exception{
    		Class c=Class.forName("com.java.demo.Person");
    		Object oj=c.newInstance();
    		System.out.println(oj);
    		Constructor con=c.getConstructor(String.class,int.class,String.class);
    		Object obj=con.newInstance("张三",18,"男");
    		System.out.println(obj);
    	}
    	//编写一个类,增加一个实例方法用于打印一条字符串。并使用反射手段创建该类的对象, 并调用该对象中的方法。
    	public static void ti3() throws Exception{
    		Class c=Class.forName("com.java.demo.Person");
    		Object obj=c.newInstance();
    		Method method=c.getMethod("run");
    		method.invoke(obj);
    	}
    	//定义一个标准的JavaBean,名叫Person,包含属性name、age。
    //	使用反射的方式创建一个实例、调用构造函数初始化name、age,使用反射方式调用setName方法对名称进行设置,
    //	不使用setAge方法直接使用反射方式对age赋值。
    	public static void ti4() throws Exception{
    		Class c=Class.forName("com.java.demo.Person");
    		Constructor con=c.getConstructor(String.class,int.class,String.class);
    		Object obj=con.newInstance("张三",14,"男");
    		System.out.println(obj);
    		Method method=c.getMethod("setName", String.class);
    		method.invoke(obj, "李四");
    		System.out.println(obj);
    		Field field=c.getDeclaredField("age");
    		field.setAccessible(true);
    		field.set(obj, 15);
    		System.out.println(obj);
    	}
    	public static void ti5() throws IOException, Exception{
    		Properties pro=new Properties();
    		FileReader fr=new FileReader("pro.properties");
    		pro.load(fr);
    		String demoName=pro.getProperty("DemoName");
    		Class c=Class.forName(demoName);
    		Object obj=c.newInstance();
    		Method method=c.getMethod("run");
    		method.invoke(obj);
    		
    	}
    }
    
  • 相关阅读:
    MVC 中的Areas支持
    webAPI 自动生成帮助文档
    ASP.NET Web API系列教程目录
    ASP.NET MVC学习系列 WebAPI初探
    win7下配置apache和php
    VS2010打不开VS2012 .NET MVC 工程,及打开后部分模块加载不正确的解决办法
    Sqlserver通过链接服务器访问Oracle的解决办法
    [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托
    [C# 基础知识系列]专题四:事件揭秘
    [C# 基础知识系列]专题十六:Linq介绍
  • 原文地址:https://www.cnblogs.com/zhangrui0328/p/9249891.html
Copyright © 2020-2023  润新知