zoukankan      html  css  js  c++  java
  • java 反射 (一)

    原文地址https://www.zhihu.com/question/24304289
     
    首先我们了解一下JVM,什么是JVM,Java的虚拟机,java之所以能跨平台就是因为这个东西,你可以理解成一个进程,程序,只不过他的作用是用来跑你的代码的。上图是java的内存模型,我们关注的点,一个方法区,一个栈,一个堆,初学的时候老师不深入的话只告诉你java的内存分为堆和栈,易懂点吧!

    作者:老顽童周伯通
    链接:https://www.zhihu.com/question/24304289/answer/147529485
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    假如你写了一段代码:Object o=new Object();

    运行了起来!

    首先JVM会启动,你的代码会编译成一个.class文件,然后被类加载器加载进jvm的内存中,你的类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个class对象,作为方法区类的数据结构的接口。jvm创建对象前,会先检查类是否加载,寻找类对应的class对象,若加载好,则为你的对象分配内存,初始化也就是代码:new Object()。

    上面的流程就是你自己写好的代码扔给jvm去跑,跑完就over了,jvm关闭,你的程序也停止了。

    为什么要讲这个呢?因为要理解反射必须知道它在什么场景下使用。

    题主想想上面的程序对象是自己new的,程序相当于写死了给jvm去跑。假如一个服务器上突然遇到某个请求哦要用到某个类,哎呀但没加载进jvm,是不是要停下来自己写段代码,new一下,哦启动一下服务器,(脑残)!

    反射是什么呢?当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,这样的好处对于服务器来说不言而喻,举个例子我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用,这时候我们的程序就写得比较动态化,通过Class tc = Class.forName("com.java.dbtest.TestConnection");通过类的全类名让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!举多个例子,大家如果接触过spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。

    ========================================================================================================================

    ========================================================================================================================

    作者:meepo
    链接:https://www.zhihu.com/question/24304289/answer/150310001
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    鉴于手机知乎上看代码格式会乱掉,所以代码都截图

    1. 首先准备两个很简单的业务类




    2. 非反射方式切换不同的业务方法调用



    当需要从第一个业务方法切换到第二个业务方法的时候,使用非反射方式,必须修改代码,并且重新编译运行,才可以达到效果

    3. 反射方式

    使用反射方式,首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。
    在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。

    当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。



    ========================================================================================================================

    ========================================================================================================================

    作者:郭无心
    链接:https://www.zhihu.com/question/24304289/answer/76541818
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。

    下面具体介绍一下java的反射机制。


    Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;
    

    其中class代表的时类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组 成部分。


    Java反射的作用:

    在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。


    Java 反射机制主要提供了以下功能

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

    反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;


    其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class类中针对这三个元素的方法:


    1、得到构造器的方法

     
    Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, 
     
    Constructor[] getConstructors() -- 获得类的所有公共构造函数 
     
    Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) 
     
    Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 
    


    2、获得字段信息的方法

    Field getField(String name) -- 获得命名的公共字段 
     
    Field[] getFields() -- 获得类的所有公共字段 
     
    Field getDeclaredField(String name) -- 获得类声明的命名的字段 
     
    Field[] getDeclaredFields() -- 获得类声明的所有字段 
    

    3、获得方法信息的方法

    Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法 
     
    Method[] getMethods() -- 获得类的所有公共方法 
     
    Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法 
     
    Method[] getDeclaredMethods() -- 获得类声明的所有方法 
    

    在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的

    如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。使用反射就可以变成“实例化对象——getClass()方法——得到完整的‘包.类’名称”这样的过程。

    正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。

    ========================================================================================================================

    ========================================================================================================================

    1,Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;

    其中class代表类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组 成部分。



    2,通过对象获取类Class c =对象.getClass()------->获取类的属性方法Method method[]=c.getMethods(),可以不用通过这个类的实例对象来执行方法

    3,静态加载是在编译的就会进行加载------静态加载的话就需要把软件全部卸载再重新编译安装
    动态加载就是在运行时才进行加载-------动态加载,只需把软件更新的部分进行重新的编译

    4,将可能需要切换改变的类/数据存放在配置文件里面,得到配置文件里面的类名称---->获取类的属性方法
    Properties p = new Properties(); p.load(fis);

    //通过key获得value
    String name= p.getProperty("className");


    //通过反射机制创建对象
    Class c =Class.forName(name);
    Object o = c.newInstance();
    配置文件(className.properties) 里面的内容是 className=java.util.Date
  • 相关阅读:
    microsoft visual studio 不能逐句执行?
    【转】字符编码笔记:ASCII,Unicode和UTF-8
    【PNG格式中文详解】
    PHP 下载网络图片
    Install MongoDB on Windows (Windows下安装MongoDB)
    S2SH商用后台权限系统第二讲
    S2SH商用后台权限系统第一讲
    linux 常用命令
    简单的angular表单验证指令
    angular随笔
  • 原文地址:https://www.cnblogs.com/111testing/p/8598618.html
Copyright © 2011-2022 走看看