• 反射


    Reflect 反射:

    所有类都是Object的子类

    所有类的对象都是Class类的实例

    反射:在程序运行期间,对于任意一个类,我们都能知道这个类中所有的属性和方法(包含私有的),这种动态的获取类的信息和动态的调用对象的方法或者属性的功能====>Java反射机制

    但是破坏了封装的安全性

    为什么需要完整限定名:

    完整限定名=包名+类名

    在同一个包中不允许出现相同的类

    确保类是唯一的

    1.Class.forName("完整限定名").getName()

    2.类名.Class.getName()

    3.对象名.getClass.getName()

    @Test
    public void Test01(){
    try {
    System.out.println("第一种式:"+Class.forName("demo3.fanshe.Student").getName());
    System.out.println("第二种方式:"+Student.class.getName());
    System.out.println("第三种方式:"+new Student().getClass().getName());
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    @Test
    public void Test02(){
    try {
    Class c = Class.forName("demo3.fanshe.Student");
    System.out.println("Student类所在的包:"+c.getPackage().getName());
    System.out.println("Student类完整限定名:"+c.getName());
    System.out.println("Student类简写的类名:"+c.getSimpleName());
    int num = c.getModifiers();
    String result = Modifier.toString(num);
    System.out.println("获取类的修饰符"+result);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    /**
    * getFields(): 只能获取public修饰的字段
    * getDeclaredFields():所有字段的集合
    */

    @Test
    public void Test03(){
    try {
    Class c = Class.forName("demo3.fanshe.Student");
    Field[] fields = c.getDeclaredFields();
    for (int i = 0; i < fields.length; i++) {
    System.out.print(fields[i].getName());
    System.out.println("对应的修饰符是:"+Modifier.toString(fields[i].getModifiers()));
    }
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    /**
    * c.getMethods() :获取所有public修饰的方法
    * c.getDeclaredMethods():获取所有的方法
    */

    @Test
    public void Test04(){
    try {
    Class c = Class.forName("demo3.fanshe.Student");
    Method[] methods = c.getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
    System.out.println(methods[i].getName());
    }
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
    }

    @Test
    public void Test05(){
    try {
    Class c = Class.forName("demo3.fanshe.Student");
    Student stu = (Student) c.newInstance();
    // stu.sex 获取不到私有的属性和私有方法
    Field field = c.getDeclaredField("sex");
    // 打开访问私有属性或者方法的开关
    field.setAccessible(true);
    System.out.println(field.get(stu));
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (NoSuchFieldException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    }
    }

    @Test
    public void Test06(){
    try {
    Class c = Class.forName("demo3.fanshe.Student");
    Student stu = (Student) c.newInstance();
    Method method = c.getDeclaredMethod("getSum", double.class);
    // 打开访问私有属性或者方法的开关
    method.setAccessible(true);
    double result = (double) method.invoke(stu, 50.0);
    System.out.println(result);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } catch (InstantiationException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    }
    }

    类的生命周期(面试题):
    01.加载 : 找到并加载我们的.class文件
    02.连接
       001.验证
       002.准备 为类中所有静态数据开辟空间,并且赋予 默认值
       003.解析 把类中所有的符号引用, 转换成直接引用
    03.初始化
    类中所有静态数据开辟空间,并且赋予 初始值

  • 相关阅读:
    KVO的用法、底层实现原理
    Runtime应用(三)实现NSCoding的自动归档和自动解档
    Runtime应用(二)使用对象关联为分类增加属性(每个对象的属性互不干扰)
    Runtime 应用(一)拦截系统自带的方法交换实现
    iOS实现传递不定长的多个参数
    Runtime 中的 _cmd、 IMP
    UIWebView、WKWebView使用详解及性能分析
    iOS
    基本图形生成算法
    关于动画中帧的解释
  • 原文地址:https://www.cnblogs.com/s10-/p/8287969.html
Copyright © 2020-2023  润新知