zoukankan      html  css  js  c++  java
  • 反射

    java 反射机制

    • 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
    • 原理
      • 手工创建对象,自己来执行类加载器(ClassLoader),调用类模板(Class)的方法获取类的信息,和创建对象
    • 创建对象方式
      1. new
        • 编译时强烈依赖类,硬编码,调用时必须有相关类才能编译通过
      2. 工厂模式
      3. 反序化
      4. 反射机制
        • 编译时不依赖类,软编码,不依赖类(传统依赖类,称为硬编码)
    • 流程
      • 获取类模板类对象
      • 创建需要的对象
      • 或许属性定义对象,再配合this对象完成对象属性的访问

    反射机制提供的功能

    • 在运行时判断任意一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时判断任意一个类所具有的成员变量和方法
    • 在运行时调用任意一个对象的成员变量和方法
    • 生成动态代理

    反射相关的主要API:

    java.lang.Class

    • Class本身也是一个类
    • Class 对象只能由系统建立对象
    • 一个类在 JVM 中只会有一个Class实例
    • 一个Class对象对应的是一个加载到JVM中的一个.class文件
    • 每个类的实例都会记得自己是由哪个 Class 实例所生成
    • 通过Class可以完整地得到一个类中的完整结构
    方法:
    方法名 功能说明
    static Class forName(String name) 返回指定类名 name 的 Class 对象
    Object newInstance() 调用缺省构造函数,返回该Class对象的一个实例
    String getName() 返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称
    Class [] getInterfaces() 获取当前Class对象的接口
    ClassLoader getClassLoader() 返回该类的类加载器
    Class getSuperclass() 返回表示此Class所表示的实体的超类的Class
    Constructor[] getConstructors() 返回一个包含某些Constructor对象的数组
    Field[] getDeclaredFields() 返回Field对象的一个数组
    Method getMethod(String name,Class … paramTypes) 返回一个Method对象,此对象的形参类型为paramType
    String str = "test4.Person";			//自定义类
    Class clazz = Class.forName(str);		//获取类模板对象
    Object obj = clazz.newInstance();		//获取对象
    Field field = clazz.getField("name");	//获取属性类对象,用来操作属性
    field.set(obj, "Peter");				//设置属性
    Object obj2 = field.get(obj);			//获取属性
    System.out.println(obj2);				//打印拿到的属性
    
    
    Class类对象获取
    1. 前提:若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
      • 实例:Class clazz = String.class;
    2. 前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
      • 实例:Class clazz = “www.atguigu.com”.getClass();
    3. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException
      • 实例:Class clazz = Class.forName(“java.lang.String”);
    4. 其他方式
      • ClassLoader cl = this.getClass().getClassLoader();//类加载器
      • Class clazz4 = cl.loadClass(“类的全类名”); //类加载器加载类模板得类模板

    ClasaLoader类,类加载器类

    • 加载类
    • 获取资源(因为类加载器的特殊性,使其有很高的权限可以访问jar和src各处,区别文件系统和包名)
    //例,类加载器获取jdk,jar,src任意目录下的资源
    public class Main4 {
    	public static void main(String[] args) {
    		
    		//由类的class属性生成加载器
    		ClassLoader classLoader = Main4.class.getClassLoader();
            //通过类加载器的getResourseAsSteam方法建立流
    		InputStream asStream = classLoader.getResourceAsStream("qw");
    		Properties properties = new Properties(); 
    		try {
    			properties.load(asStream);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		Enumeration propertyNames = properties.propertyNames();
    		while (propertyNames.hasMoreElements()) {
    			Object object = (Object) propertyNames.nextElement();
    			Object object2 = properties.get(object);
    			System.out.println(object + " : " + object2);
    		}
    	}
    }
    
    
    java.lang.reflect.Method
    • 方法类对象
      1. Object invoke(Object obj, Object … args) //对象执行,配合对象使用
      2. public void setAccessible(true)//继承自AccessibleObject设置私有方法可见,暴力破解封装性,唯一破解封装性的方法
    java.lang.reflect.Field
    • 属性类对象
      1. public Object get(Object obj) //获取属性对象,配合对象使用
      2. public void set(Object obj,Object value) //设置属性
      3. public void setAccessible(true)//继承自AccessibleObject设置属性可见,暴力破解封装性,唯一破解封装性的方法
    java.lang.reflect.Constructor
    • 构造器对象

    类加载过程

    • 类的加载:将类的class文件读入内存,并为之创建一个java.lang.Class对象。此过程由类加载器完成
    • 类的连接:将类的二进制数据合并到JRE中
    • 类的初始化:JVM负责对类进行初始化

    加载器分类

    • 引导类加载器:加载核心类库
      • 扩展类加载器:加载jar包下的整合框架类库
        • 系统类加载器:加载用户类
    • 双亲调用机制
      • 双亲是:扩展类加载器,引导类加载器
      • 流程
        • 系统加载器首先调用扩展类类加载器加载,
        • 扩展类加载器首先调用引导类加载器加载,
        • 引导类查找是否属于核心类库,有则加载,无则返回
        • 若返回,则扩展类查找是否属于自己的
      • 向上提交,回朔加载,先尝试委派父类加载器加载器加载,被驳回则扫描自己地区域,
      • 目的:安全

  • 相关阅读:
    Codeforces Round #536 E. Lunar New Year and Red Envelopes /// 贪心 记忆化搜索 multiset取最大项
    牛客网暑期ACM多校训练营(第五场) F
    关于线段树or 树状树状 在二维平面搞事情!Orz
    ZOJ 3822 ( 2014牡丹江区域赛D题) (概率dp)
    HDU4336 Card Collector (概率dp+状压dp)
    POJ 2151 Check the difficulty of problems(概率DP)
    CF E2
    HDU4089 Activation(概率DP+处理环迭代式子)
    HDU4035 Maze (概率DP)
    牛客 Rabbit的数列 (线段树维护值为x的个数+区间覆盖)
  • 原文地址:https://www.cnblogs.com/refengqingfu/p/10014718.html
Copyright © 2011-2022 走看看