zoukankan      html  css  js  c++  java
  • 03.反射杂谈

    1.什么是反射?
    反射就是动态加载对象,并对对象进行剖析。在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取信息以及动态调用对象方法的功能成为Java反射机制。
     
    2.Java反射机制的作用
    1). 在运行时判断任意一个对象所属的类
    2). 在运行时构造任意一个类的对象
    3). 在运行时判断任意一个类所具有的成员变量和方法
    4). 在运行时调用任意一个对象的方法
     
    3.java反射机制提供了什么功能?
    1). 在运行时能够判断任意一个对象所属的类
    2). 在运行时构造任意一个类的对象
    3). 在运行时判断任意一个类所具有的成员变量和方法
    4). 在运行时调用任一对象的方法
    5). 在运行时创建新类对象
     
    4.哪里用到反射机制?
    各种框架用的最多的就是反射
    加载驱动
    读取配置文件
     
    5.运用反射的优缺点
    优点:
        反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类
    缺点:
       (1)性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
       (2)使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
     
    6.如何使用java的反射?
    a. 通过一个全限类名创建一个对象
    1)、Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了
    2)、类名.class; 获取Class<?> clz 对象
    3)、对象.getClass();
    b. 获取构造器对象,通过构造器new出一个对象
    1). Class.getConstructor([String.class]);
    2). Con.newInstance([参数]);
    c. 通过class对象创建一个实例对象(就相当与new类名()无参构造器)
    1). Class.newInstance();
    d. 通过class对象获得一个属性对象
    1)、Field c=clz.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
    2)、Field c=clz.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段 e.
    e、通过class对象获得一个方法对象
    1). Class.getMethod(“方法名”,class……parameaType);(只能获取公共的)
    2). Class.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
    3) M.setAccessible(true);(让私有的方法可以执行)
    f. 让方法执行
    1). Method.invoke(obj实例对象,obj可变参数);-----(有返回值的)
     
    7.反射重要借助哪四个类?
    1)、Class:类的对象;
    2)、Constructor:类的构造方法
    3)、Field:类中的属性对象
    4)、Method:类中的方法对象
     
    8.获得一个类的类对象有哪些方式?
     
    方法1:类型.class,例如:String.class
     
    方法2:对象.getClass(),例如:"hello".getClass()
     
     方法3:Class.forName(),例如:Class.forName("java.lang.String")
     
    9.如何通过反射创建对象?

    方法1:通过类对象调用newInstance()方法,例如:String.class.newInstance()
     
    方法2:通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,例如:String.class.getConstructor(String.class).newInstance("Hello");
     
    10.如何通过反射获取和设置对象私有字段的值?
    可以通过类对象的getDeclaredField()方法字段(Field)对象,然后再通过字段对象的setAccessible(true)将其设置为可以访问,接下来就可以通过get/set方法来获取/设置字段的值了。
     
    11.如何通过反射调用对象的方法?
    import java.lang.reflect.Method;
    class MethodInvokeTest {
        public static void main(String[] args) throws Exception {
            String str = "hello";
            Method m = str.getClass().getMethod("toUpperCase");
            System.out.println(m.invoke(str));  // HELLO
        }
    }
     
    12.反射中,Class.forName 和 ClassLoader 区别。
    Class.forName(className)方法,其实调用的方法是Class.forName(className,true,classloader);注意看第2个boolean参数,它表示的意思,在loadClass后必须初始化。比较下我们前面准备jvm加载类的知识,我们可以清晰的看到在执行过此方法后,目标对象的 static块代码已经被执行,static参数也已经被初始化。
     再看ClassLoader.loadClass(className)方法,其实他调用的方法是ClassLoader.loadClass(className,false);还是注意看第2个 boolean参数,该参数表示目标对象被装载后不进行链接,这就意味这不会去执行该类静态块中间的内容
     
    13.如何获取类的class对象
    Class 类的实例表示正在运行的 Java 应用程序中的类和接口。
    获取类的Class对象有多种方式:
    调用getClass

    Boolean var1 = true;
    Class<?> classType2 = var1.getClass();
    System.out.println(classType2);
    输出:class java.lang.Boolean
     
    运用.class 语法

    Class<?> classType4 = Boolean.class;
    System.out.println(classType4);
    输出:class java.lang.Boolean
     
    运用static method Class.forName()

    Class<?> classType5 = Class.forName("java.lang.Boolean");
    System.out.println(classType5);
    输出:class java.lang.Boolean
     
    运用primitive wrapper classes的TYPE 语法
    这里返回的是原生类型,和Boolean.class返回的不同
     
    Class<?> classType3 = Boolean.TYPE;
    System.out.println(classType3);   输出:boolean
     
    14.如何获取类的fields
    可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。JAVA 的Class<T>类提供了几个方法获取类的属性。

    public FieldgetField(String name)
    返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段

    public Field[]
     getFields()
    返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段

    public FieldgetDeclaredField(Stringname)
    返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段

    public Field[]
     getDeclaredFields()

    返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
     
    15.如何获取类的constructor
    通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
    ,Class<T>类提供了几个方法获取类的构造器。
    public Constructor<T>
     getConstructor(Class<?>...
     parameterTypes)
    返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
    public Constructor<?>[]
     getConstructors()
    返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法
    public Constructor<T>
     getDeclaredConstructor(Class<?>...
     parameterTypes)
    返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法
    public Constructor<?>[]
     getDeclaredConstructors()
    返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法
  • 相关阅读:
    Mysql 主从设置
    HTTP协议--请求与响应
    Memcahce(MC)系列(一)Memcache介绍、使用、存储、算法、优化
    Nginx配置性能优化
    PHP版本--HTTP session cookie原理及应用
    MYSQL 优化常用方法
    linux查询系统负载
    一群猴子排成一圈,按1,2,...,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈
    数据库SQL SELECT查询的工作原理
    Unity使用UGUI进行VR游戏的界面开发
  • 原文地址:https://www.cnblogs.com/wangdh666/p/10738875.html
Copyright © 2011-2022 走看看