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

  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/refengqingfu/p/10014718.html
Copyright © 2011-2022 走看看