精华内容
下载资源
问答
  • 前面给大家介绍了一下什么是java反射机制,那么下面要给大家介绍的就是java反射机制的原理,那么它的原理究竟是怎样的呢?下面就通过下面来做一下详细的了解吧。首先我们再来介绍一下java反射机制。java反射机制就是...

    前面给大家介绍了一下什么是java反射机制,那么下面要给大家介绍的就是java反射机制的原理,那么它的原理究竟是怎样的呢?下面就通过下面来做一下详细的了解吧。

    首先我们再来介绍一下java反射机制。

    java反射机制就是java程序在运行的时候动态的创建类并调用类的方法以及属性。

    下面就来介绍一下原理。

    一、java反射机制原理

    下面是我们经常可以见到的反射例子:Class

    > clz = Class.forName("java.util.ArrayList");

    ArrayList object = (ArrayList) clz.newInstance();

    Method method = clz.getMethod("add",Object.class);

    method.invoke(list , "sss");

    来分析一下:

    前面的2行实现了类的装载、链接、初始化。

    后面的2行实现了从class对象当中,获取对象,之后执行反射调用。

    这里的话让我们来设想一下,如果,要实现Invoke方法,那么是不是只要实现下面的类就可以了呢?public class Method

    {

    public void invoke(Object obj, Object...args)

    {

    ArrayList list = (ArrayList) obj;

    list.add(args);

    }

    }

    反射的原理之一就是动态的生成类似上面的字节码,加载到jvm当中运行。

    再一起来看看Method对象流程。

    上面的Class对象是在加载类的时候,由jvm构造的。

    jvm为每一个类管理一个独一无二的Class对象,这个Class对象里维护着这个类的所有

    Method、Field、Constructor的cache,这份cache可以被叫做是根对象,每一次,getMethod获取到的Method对象都持有对根对象的引用。

    由于一些重量级的Method的成员变量,大多数都不希望每次在创建Method对象的时候,都要重新进初始化,所以,所有代表同一个方法的Method对象都共享着根对象的MethodAccessor,每一次创建都会调用根对象的copy方法复制一份。Method copy()

    {

    Method res = new Method(clazz, name, parameterTypes, returnType

    , exceptionTypes, modifiers, slot, signature

    , annotations, parameterAnnotations, annotationDefault);

    res.root = this;

    res.methodAccessor = methodAccessor;

    return res;

    }

    调用invoke方法流程

    首先的话,method.invoke方法会获取一个MethodAccessor。

    会先从Method的根对象当中获取MethodAccessor。

    假如是空,那么用reflectionFactory.newMethodAccessor返回DelegatingMethodAccessorImpl实例。

    之后再把MethodAccessor赋值给Method的root对象当中,之后调用DelegatingMethodAccessorImpl当中的invoke方法。

    在调用invoke的次数大于15次之后,MethodAccessor将由java代码生成。

    关于java反射机制原理就给你介绍到这里了,更多java反射机制常见问题,可以继续关注本站来了解。

    推荐阅读:

    展开全文
  • java反射原理、作用

    2021-04-09 11:11:07
    1.什么是反射反射原理java反射原理:java类的执行需要经历以下过程,编译:.java文件编译后生成.class字节码文件加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区...

    1.什么是反射,反射原理java反射的原理:java类的执行需要经历以下过程,编译:.java文件编译后生成.class字节码文件

    加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例

    连接:细分三步

    验证:格式(class文件规范) 语义(final类是否有子类) 操作

    准备:静态变量赋初值和内存空间,final修饰的内存空间直接赋原值,此处不是用户指定的初值。

    解析:符号引用转化为直接引用,分配地址

    初始化:有父类先初始化父类,然后初始化自己;将static修饰代码执行一遍,如果是静态变量,则用用户指定值覆盖原有初值;如果是代码块,则执行一遍操作。

    Java的反射就是利用上面第二步加载到jvm中的.class文件来进行操作的。.class文件中包含java类的所有信息,当你不知道某个类具体信息时,可以使用反射获取class,然后进行各种操作。

    Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。总结说:反射就是把java类中的各种成分映射成一个个的Java对象,并且可以进行操作。

    2.获取class的三种方式先定义一个实体类Person:Package reflex;

    public class Person {

    //私有属性

    private String name = "Tom";

    //公有属性

    public int age = 18;

    //构造方法

    public Person() {

    }

    //私有方法

    private void say(){

    System.out.println("private say()...");

    }

    //公有方法

    public void work(){

    System.out.println("public work()...");

    }

    }

    获取class方法 (类 对象 Class)

    //1、对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object

    // 类型的对象,而我不知道你具体是什么类,用这种方法

    Person p1 = new Person();

    Class c1 = p1.getClass();

    //2、类名.class 的方式得到,该方法最为安全可靠,程序性能更高

    // 这说明任何一个类都有一个隐含的静态成员变量 class

    Class c2 = Person.class;

    //3、通过 Class 对象的 forName() 静态方法来获取,用的最多,

    // 但可能抛出 ClassNotFoundException 异常

    Class c3 = Class.forName("reflex.Person");

    需要注意的是:一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的 c1,c2,c3进行 equals 比较,发现都是true。代码如下:Class class1 = Person.class;

    Person person = new Person();

    Class class2= person.getClass();

    if(class1.equals(class2)){

    System.out.println("class1.equals(class2)");

    }

    Class具有的部分方法如下:

    getName():获得类的完整名字。

    getFields():获得类的public类型的属性。

    getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

    getMethods():获得类的public类型的方法。

    getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

    getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

    getConstructors():获得类的public类型的构造方法。

    getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

    newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

    3.Class能实现的功能

    1判断对象属于哪个类Person person = new Person();

    Class class2= person.getClass();

    System.out.println("class2:"+class2);

    输出:class2:class reflect.Person

    2获取类信息Class class1 = Person.class;

    Method[] methods = class1.getMethods();

    Method[] declaredMethods = class1.getDeclaredMethods();

    Field[] declaredFields = class1.getDeclaredFields();

    3构建对象Person person = new Person();

    Class class2= person.getClass();

    Object o = class2.newInstance();

    //强转前先用instanceof判断

    if(o instanceof Person){

    ((Person) o).work();

    }

    4动态执行方法Class class1 = Person.class;

    Method work = class1.getDeclaredMethod("work");

    Person person = new Person();

    work.invoke(person);

    5动态操作属性Class class1 = Person.class;

    Person person = new Person();

    Field field = class1.getDeclaredField("age");

    //age默认值是18

    field.set(person,22);

    System.out.println(person.age);

    4.jdk源码对反射的使用实例

    LongAdder中,运用反射获取某属性的偏移值,方便Unsafe类直接获取某属性的值// Unsafe mechanics Unsafe相关的初始化

    private static final sun.misc.Unsafe UNSAFE;

    private static final long valueOffset;

    static {

    try {

    UNSAFE = sun.misc.Unsafe.getUnsafe();

    Class> ak = Cell.class;

    // 获取类中属性的偏移值

    valueOffset = UNSAFE.objectFieldOffset (ak.getDeclaredField("value"));

    } catch (Exception e) {

    throw new Error(e);

    }

    }

    final boolean cas(long cmp, long val) {

    return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);

    }

    5.什么时候应该使用反射?

    1)反射构建出无法直接访问的类:例如可以把完整的包+类名称放到properties中,java中获取,然后就可以根据这个配置获取class了,然后你就可以干很多事

    Class.forName("name");

    2)调用不可访问的方法

    3)简化代码

    展开全文
  • java反射机制原理详解

    2021-03-22 13:49:40
    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java反射机制。这里你将颠覆原来对java的理解。Java反射机制的...

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java的反射机制。这里你将颠覆原来对java的理解。

    Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;其中class代表的时类对

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

    成部分。

    Class:程序运行时,java运行时系统会对所有的对象进行运行时类型的处理。这项信息记录了每个对象所属的类,虚拟机通常使用运行时类型信息选择正

    确的方法来执行(摘自:白皮书)。但是这些信息我们怎么得到啊,就要借助于class类对象了啊。在Object类中定义了getClass()方法。我

    们可以通过这个方法获得指定对象的类对象。然后我们通过分析这个对象就可以得到我们要的信息了。

    比如:ArrayList arrayList;

    Class clazz = arrayList.getClass();

    然后我来处理这个对象clazz。

    当然了Class类具有很多的方法,这里重点将和Constructor,Field,Method类有关系的方法。

    Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java

    程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。Java

    的这一能力在实际应用中也许用得不是很多,但是个人认为要想对java有个更加深入的了解还是应该掌握的。

    1.检测类:

    reflection的工作机制

    考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。

    import java.lang.reflect.*;

    public class DumpMethods {

    public static void main(String args[]) {

    try {

    Class c = Class.forName(args[0]);

    Method m[] = c.getDeclaredMethods();

    for (int i = 0; i < m.length; i++)

    System.out.println(m[i].toString());

    } catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    按如下语句执行:

    java DumpMethods java.util.ArrayList

    这个程序使用 Class.forName 载入指定的类,然后调用 getDeclaredMethods

    来获取这个类中定义了的方法列表。java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类。

    Java类反射中的主要方法

    对于以下三类组件中的任何一类来说 -- 构造函数、字段和方法 -- java.lang.Class

    提供四种独立的反射调用,以不同的方式来获得信息。调用都遵循一种标准格式。以下是用于查找构造函数的一组反射调用:

    Constructor getConstructor(Class[] params) --

    获得使用特殊的参数类型的公共构造函数,

    Constructor[] getConstructors() -- 获得类的所有公共构造函数

    Constructor getDeclaredConstructor(Class[] params) --

    获得使用特定参数类型的构造函数(与接入级别无关)

    Constructor[] getDeclaredConstructors() --

    获得类的所有构造函数(与接入级别无关)

    获得字段信息的Class 反射调用不同于那些用于接入构造函数的调用,在参数类型数组中使用了字段名:

    Field getField(String name) -- 获得命名的公共字段

    Field[] getFields() -- 获得类的所有公共字段

    Field getDeclaredField(String name) -- 获得类声明的命名的字段

    Field[] getDeclaredFields() -- 获得类声明的所有字段

    用于获得方法信息函数:

    Method getMethod(String name, Class[] params) --

    使用特定的参数类型,获得命名的公共方法

    Method[] getMethods() -- 获得类的所有公共方法

    Method getDeclaredMethod(String name, Class[] params) --

    使用特写的参数类型,获得类声明的命名的方法

    Method[] getDeclaredMethods() -- 获得类声明的所有方法

    使用 Reflection:

    用于 reflection 的类,如 Method,可以在 java.lang.relfect

    包中找到。使用这些类的时候必须要遵循三个步骤:第一步是获得你想操作的类的 java.lang.Class 对象。在运行中的 Java

    程序中,用 java.lang.Class 类来描述类和接口等。

    下面就是获得一个 Class 对象的方法之一:

    Class c = Class.forName("java.lang.String");

    这条语句得到一个 String 类的类对象。还有另一种方法,如下面的语句:

    Class c = int.class;

    或者

    Class c = Integer.TYPE;

    它们可获得基本类型的类信息。其中后一种方法中访问的是基本类型的封装类 (如 Intege ) 中预先定义好的 TYPE

    字段。

    第二步是调用诸如 getDeclaredMethods 的方法,以取得该类中定义的所有方法的列表。

    一旦取得这个信息,就可以进行第三步了——使用 reflection API 来操作这些信息,如下面这段代码:

    Class c = Class.forName("java.lang.String");

    Method m[] = c.getDeclaredMethods();

    System.out.println(m[0].toString());

    它将以文本方式打印出 String 中定义的第一个方法的原型。

    处理对象:

    a.创建一个Class对象

    b.通过getField 创建一个Field对象

    c.调用Field.getXXX(Object)方法(XXX是Int,Float等,如果是对象就省略;Object是指实例).

    例如:

    import java.lang.reflect.*;

    import java.awt.*;

    class SampleGet {

    public static void main(String[] args) {

    Rectangle r = new Rectangle(100, 325);

    printHeight(r);

    }

    static void printHeight(Rectangle r) {

    Field heightField;

    Integer heightValue;

    Class c = r.getClass();

    try {

    heightField = c.getField("height");

    heightValue = (Integer) heightField.get(r);

    System.out.println("Height: " + heightValue.toString());

    } catch (NoSuchFieldException e) {

    System.out.println(e);

    } catch (SecurityException e) {

    System.out.println(e);

    } catch (IllegalAccessException e) {

    System.out.println(e);

    }

    }

    }

    安全性和反射:

    在处理反射时安全性是一个较复杂的问题。反射经常由框架型代码使用,由于这一点,我们可能希望框架能够全面接入代码,无需考虑常规的接入限制。但是,在其它情况下,不受控制的接入会带来严重的安全性风险,例如当代码在不值得信任的代码共享的环境中运行时。

    由于这些互相矛盾的需求,Java编程语言定义一种多级别方法来处理反射的安全性。基本模式是对反射实施与应用于源代码接入相同的限制:

    从任意位置到类公共组件的接入

    类自身外部无任何到私有组件的接入

    受保护和打包(缺省接入)组件的有限接入

    不过至少有些时候,围绕这些限制还有一种简单的方法。我们可以在我们所写的类中,扩展一个普通的基本类

    java.lang.reflect.AccessibleObject

    类。这个类定义了一种setAccessible方法,使我们能够启动或关闭对这些类中其中一个类的实例的接入检测。唯一的问题在于如果使用了安全性管理

    器,它将检测正在关闭接入检测的代码是否许可了这样做。如果未许可,安全性管理器抛出一个例外。

    下面是一段程序,在TwoString 类的一个实例上使用反射来显示安全性正在运行:

    public class ReflectSecurity {

    public static void main(String[] args) {

    try {

    TwoString ts = new TwoString("a", "b");

    Field field = clas.getDeclaredField("m_s1");

    // field.setAccessible(true);

    System.out.println("Retrieved value is " +

    field.get(inst));

    } catch (Exception ex) {

    ex.printStackTrace(System.out);

    }

    }

    }

    如果我们编译这一程序时,不使用任何特定参数直接从命令行运行,它将在field

    .get(inst)调用中抛出一个IllegalAccessException异常。如果我们不注释

    field.setAccessible(true)代码行,那么重新编译并重新运行该代码,它将编译成功。最后,如果我们在命令行添加了JVM参数

    -Djava.security.manager以实现安全性管理器,它仍然将不能通过编译,除非我们定义了ReflectSecurity类的许可权

    限。

    反射性能:(转录别人的啊)

    反射是一种强大的工具,但也存在一些不足。一个主要的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

    下面的程序是字段接入性能测试的一个例子,包括基本的测试方法。每种方法测试字段接入的一种形式 -- accessSame

    与同一对象的成员字段协作,accessOther 使用可直接接入的另一对象的字段,accessReflection

    使用可通过反射接入的另一对象的字段。在每种情况下,方法执行相同的计算 -- 循环中简单的加/乘顺序。

    程序如下:

    public int accessSame(int loops) {

    m_value = 0;

    for (int index = 0; index < loops; index++) {

    m_value = (m_value + ADDITIVE_VALUE) *

    MULTIPLIER_VALUE;

    }

    return m_value;

    }

    public int acces

    sReference(int loops) {

    TimingClass timing = new TimingClass();

    for (int index = 0; index < loops; index++) {

    timing.m_value = (timing.m_value + ADDITIVE_VALUE) *

    MULTIPLIER_VALUE;

    }

    return timing.m_value;

    }

    public int accessReflection(int loops) throws Exception {

    TimingClass timing = new TimingClass();

    try {

    Field field = TimingClass.class.

    getDeclaredField("m_value");

    for (int index = 0; index < loops; index++) {

    int value = (field.getInt(timing) +

    ADDITIVE_VALUE) * MULTIPLIER_VALUE;

    field.setInt(timing, value);

    }

    return timing.m_value;

    } catch (Exception ex) {

    System.out.println("Error using reflection");

    throw ex;

    }

    }

    在上面的例子中,测试程序重复调用每种方法,使用一个大循环数,从而平均多次调用的时间衡量结果。平均值中不包括每种方法第一次调用的时间,因此初始化时间不是结果中的一个因素。下面的图清楚的向我们展示了每种方法字段接入的时间:

    图 1:字段接入时间 :

    我们可以看出:在前两副图中(Sun JVM),使用反射的执行时间超过使用直接接入的1000倍以上。通过比较,IBM

    JVM可能稍好一些,但反射方法仍旧需要比其它方法长700倍以上的时间。任何JVM上其它两种方法之间时间方面无任何显著差异,但IBM

    JVM几乎比Sun JVM快一倍。最有可能的是这种差异反映了Sun Hot Spot

    JVM的专业优化,它在简单基准方面表现得很糟糕。反射性能是Sun开发1.4

    JVM时关注的一个方面,它在反射方法调用结果中显示。在这类操作的性能方面,Sun 1.4.1

    JVM显示了比1.3.1版本很大的改进。

    如果为为创建使用反射的对象编写了类似的计时测试程序,我们会发现这种情况下的差异不象字段和方法调用情况下那么显著。使用newInstance()调

    用创建一个简单的java.lang.Object实例耗用的时间大约是在Sun 1.3.1 JVM上使用new

    Object()的12倍,是在IBM 1.4.0 JVM的四倍,只是Sun 1.4.1

    JVM上的两部。使用Array.newInstance(type, size)创建一个数组耗用的时间是任何测试的JVM上使用new

    type[size]的两倍,随着数组大小的增加,差异逐步缩小。随着jdk6.0的推出,反射机制的性能也有了很大的提升。期待中….

    总结:

    Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。这些特性使得反射

    特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。Java

    reflection 非常有用,它使类和数据结构能按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。Java

    的这一特性非常强大,并且是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的。

    但反射有两个缺点。第一个是性能问题。用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相

    对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。仅反射在性能关键的应用的核心逻辑中使用时性

    能问题才变得至关重要。

    许多应用中更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问

    题。反射代码比相应的直接代码更复杂,正如性能比较的代码实例中看到的一样。解决这些问题的最佳方案是保守地使用反射——仅在它可以真正增加灵活性的地方

    ——记录其在目标类中的使用。

    一下是对应各个部分的例子:

    具体的应用:

    1、 模仿instanceof 运算符号

    class A {}

    public class instance1 {

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("A");

    boolean b1

    = cls.isInstance(new Integer(37));

    System.out.println(b1);

    boolean b2 = cls.isInstance(new A());

    System.out.println(b2);

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    2、 在类中寻找指定的方法,同时获取该方法的参数列表,例外和返回值

    import java.lang.reflect.*;

    public class method1 {

    private int f1(

    Object p, int x) throws NullPointerException

    {

    if (p == null)

    throw new NullPointerException();

    return x;

    }

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("method1");

    Method methlist[]

    = cls.getDeclaredMethods();

    for (int i = 0; i < methlist.length;

    i++)

    Method m = methlist[i];

    System.out.println("name

    = " + m.getName());

    System.out.println("decl class = " +

    m.getDeclaringClass());

    Class pvec[] = m.getParameterTypes();

    for (int j = 0; j < pvec.length; j++)

    System.out.println("

    param #" + j + " " + pvec[j]);

    Class evec[] = m.getExceptionTypes();

    for (int j = 0; j < evec.length; j++)

    System.out.println("exc #" + j

    + " " + evec[j]);

    System.out.println("return type = " +

    m.getReturnType());

    System.out.println("-----");

    }

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    3、 获取类的构造函数信息,基本上与获取方法的方式相同

    import java.lang.reflect.*;

    public class constructor1 {

    public constructor1()

    {

    }

    protected constructor1(int i, double d)

    {

    }

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("constructor1");

    Constructor ctorlist[]

    = cls.getDeclaredConstructors();

    for (int i = 0; i < ctorlist.length; i++) {

    Constructor ct = ctorlist[i];

    System.out.println("name

    = " + ct.getName());

    System.out.println("decl class = " +

    ct.getDeclaringClass());

    Class pvec[] = ct.getParameterTypes();

    for (int j = 0; j < pvec.length; j++)

    System.out.println("param #"

    + j + " " + pvec[j]);

    Class evec[] = ct.getExceptionTypes();

    for (int j = 0; j < evec.length; j++)

    System.out.println(

    "exc #" + j + " " + evec[j]);

    System.out.println("-----");

    }

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    4、 获取类中的各个数据成员对象,包括名称。类型和访问修饰符号

    import java.lang.reflect.*;

    public class field1 {

    private double d;

    public static final int i = 37;

    String s = "testing";

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("field1");

    Field fieldlist[]

    = cls.getDeclaredFields();

    for (int i

    = 0; i < fieldlist.length; i++) {

    Field fld = fieldlist[i];

    System.out.println("name

    = " + fld.getName());

    System.out.println("decl class = " +

    fld.getDeclaringClass());

    System.out.println("type

    = " + fld.getType());

    int mod = fld.getModifiers();

    System.out.println("modifiers = " +

    Modifier.toString(mod));

    System.out.println("-----");

    }

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    5、 通过使用方法的名字调用方法

    import java.lang.reflect.*;

    public class method2 {

    public int add(int a, int b)

    {

    return a + b;

    }

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("method2");

    Class partypes[] = new Class[2];

    partypes[0] = Integer.TYPE;

    partypes[1] = Integer.TYPE;

    Method meth = cls.getMethod(

    "add", partypes);

    method2 methobj = new method2();

    Object arglist[] = new Object[2];

    arglist[0] = new Integer(37);

    arglist[1] = new Integer(47);

    Object retobj

    = meth.invoke(methobj, arglist);

    Integer retval = (Integer)retobj;

    System.out.println(retval.intValue());

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    6、 创建新的对象

    import java.lang.reflect.*;

    public class constructor2 {

    public constructor2()

    {

    }

    public constructor2(int a, int b)

    {

    System.out.println(

    "a = " + a + " b = " + b);

    }

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("constructor2");

    Class partypes[] = new Class[2];

    partypes[0] = Integer.TYPE;

    partypes[1] = Integer.TYPE;

    Constructor ct

    = cls.getConstructor(partypes);

    Object arglist[] = new Object[2];

    arglist[0] = new Integer(37);

    arglist[1] = new Integer(47);

    Object retobj = ct.newInstance(arglist);

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    7、 变更类实例中的数据的值

    import java.lang.reflect.*;

    public class field2 {

    public double d;

    public static void main(String args[])

    {

    try {

    Class cls = Class.forName("field2");

    Field fld = cls.getField("d");

    field2 f2obj = new field2();

    System.out.println("d = " + f2obj.d);

    fld.setDouble(f2obj, 12.34);

    System.out.println("d = " + f2obj.d);

    }

    catch (Throwable e) {

    System.err.println(e);

    }

    }

    }

    使用反射创建可重用代码:

    1、 对象工厂

    Object factory(String p) {

    Class c;

    Object o=null;

    try {

    c = Class.forName(p);// get class def

    o = c.newInstance(); // make a new one

    } catch (Exception e) {

    System.err.println("Can't make a " + p);

    }

    return o;

    }

    public class ObjectFoundry {

    public static Object factory(String p)

    throws ClassNotFoundException,

    InstantiationException,

    IllegalAccessException {

    Class c = Class.forName(p);

    Object o = c.newInstance();

    return o;

    }

    }

    2、 动态检测对象的身份,替代instanceof

    public static boolean

    isKindOf(Object obj, String type)

    throws ClassNotFoundException {

    // get the class def for obj and type

    Class c = obj.getClass();

    Class tClass = Class.forName(type);

    while ( c!=null ) {

    if ( c==tClass ) return true;

    c = c.getSuperclass();

    }

    return false;

    }

    展开全文
  • java反射原理,作用

    2021-02-12 14:59:12
    什么是反射反射原理java类的执行需要经历以下过程编译:.java文件编译后生成.class字节码文件加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其...

    什么是反射,反射原理

    java类的执行需要经历以下过程

    编译:.java文件编译后生成.class字节码文件

    加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例

    连接:细分三步

    验证:格式(class文件规范) 语义(final类是否有子类) 操作

    准备:静态变量赋初值和内存空间,final修饰的内存空间直接赋原值,此处不是用户指定的初值。

    解析:符号引用转化为直接引用,分配地址

    初始化:有父类先初始化父类,然后初始化自己;将static修饰代码执行一遍,如果是静态变量,则用用户指定值覆盖原有初值;如果是代码块,则执行一遍操作。

    什么是反射:

    Java的反射就是利用上面第二步加载到jvm中的.class文件来进行操作的。.class文件中包含java类的所有信息,当你不知道某个类具体信息时,可以使用反射获取class,然后进行各种操作。

    Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性

    要想解剖一个类,必须先要获取到该类的字节码文件对象(class)。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.)

    关于class对象和这个Class类

    Class对象的由来是将class文件读入内存,并为之创建一个Class对象

    ed226da75b81460eeed0daa2553364c9.png

    Class类

    class类:代表一个类,是Java反射机制的起源和入口

    用于获取与类相关的各种信息, 提供了获取类信息的相关方法

    Class类继承自Object类

    Class类是所有类的共同的图纸

    每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。

    获取class对象(反射入口)的三种方式

    要想操作反射,必须先拿到反射的入口

    1,通过通过Class.forName("全类名")静态方法来获取,用的最多

    Class c3 = Class.forName("reflect_fanshe.Person");

    Class> perClazz = Class.forName("reflect_fanshe.Person");

    2,类名.class

    /2、类名.class 的方式得到,该方法最为安全可靠,程序性能更高

    //  这说明任何一个类都有一个隐含的静态成员变量 class

    Class c2 = Person.class;

    Class> perClazz2 = Person.class;

    3,对象.getClass()

    Person person = newPerson();

    Class> perClazz3 = person.getClass();

    Class具有的部分方法如下:

    getName():获得类的完整名字。

    getFields():获得类的public类型的属性。

    getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

    getMethods():获得类的public类型的方法。

    getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

    getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

    getConstructors():获得类的public类型的构造方法。

    getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

    newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

    通过反射获取对象的实例,并操作对象

    1,class.newInstance() ,并强转类型,然后就可以操作对象了,主要是调用方法。

    bf285069ac4c67c1cede951e5c3eb74f.png

    2,操作属性,可以操作类里面的public属性和private属性  如果属性是private,正常情况下是不允许外界操作属性值,这里可以用Field类的setAccessible(true)方法,暂时打开操作的权限

    e606fb75ff2527ee3154587a44337503.png

    反射方法的使用之---通过反射运行配置文件内容

    student类:

    public classStudent {public voidshow(){

    System.out.println("is show()");

    }

    }

    配置文件以txt文件为例子(pro.txt):

    className =cn.fanshe.Student

    methodName= show

    测试类:

    importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;importjava.lang.reflect.Method;importjava.util.Properties;/** 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改

    * 我们只需要将新类发送给客户端,并修改配置文件即可*/

    public classDemo {public static void main(String[] args) throwsException {//通过反射获取Class对象

    Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"//2获取show()方法

    Method m = stuClass.getMethod(getValue("methodName"));//show//3.调用show()方法

    m.invoke(stuClass.getConstructor().newInstance());

    }//此方法接收一个key,在配置文件中获取相应的value

    public static String getValue(String key) throwsIOException{

    Properties pro= new Properties();//获取配置文件的对象

    FileReader in = new FileReader("pro.txt");//获取输入流

    pro.load(in);//将流加载到配置文件对象中

    in.close();return pro.getProperty(key);//返回根据key获取的value值

    }

    }

    控制台输出:is show()

    需求:

    当我们升级这个系统时,不要Student类,而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动

    新写一个student2的类:

    public classStudent2 {public voidshow2(){

    System.out.println("is show2()");

    }

    }

    配置文件更改为:

    className =cn.fanshe.Student2

    methodName= show2

    控制台输出:is show2()

    展开全文
  • Java反射机制及原理

    2021-02-12 21:09:57
    一、概念java程序运行时动态的创建类并调用类的方法和属性二、原理简介Class> clz = Class.forName("java.util.ArrayList");ArrayList object = (ArrayList) clz.newInstance();Method method = clz.getMethod(...
  • Java反射机制实现原理

    2021-02-28 13:36:17
    ---嘿嘿,答案是肯定的,JAVA提供了反射机制可以实现。反射Java可以提供的一个灵活又强大的功能。使用Java反射,您可以知道这个类在运行时具有什么属性和方法,也可以修改属性,调用方法,创建类的实例。反射是指...
  • Java反射实现原理

    2021-03-04 06:38:35
    Java反射应用十分广泛,例如spring的核心功能控制反转IOC就是通过反射来实现的,本文主要研究一下发射方法调用的实现方式和反射对性能的影响。如下为Method类中invoke方法,可以看出该方法实际是将反射方法的调用...
  • 一、 原理简单的来说,反射机制其实就是指程序在运行的时候能够获取自身的信息。如果知道一个类的名称/或者它的一个实例对象, 就能把这个类的所有方法和变量的信息(方法名,变量名,方法,修饰符,类型,方法参数...
  • java反射原理

    2021-03-08 19:22:54
    一、预先需要掌握的知识(java虚拟机)java虚拟机的方法区:java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。方法区的主要作用是存储被装载的类的类型信息,当...
  • 展开全部反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。32313133353236313431303231363533e58685e5aeb931333262353938通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍...
  • )无论什么Java技术岗位,Java反射原理,在面试中出现的次数很多,所以我面试之前也有所准备,于是今天结合面试问题先详细讲一讲Java反射原理JAVA反射机制JAVA反射机制是在运行状态中,对于任意一个类,...
  • 一、Java 反射原理、 二、反射作用、 三、反射用法、
  • Java反射原理,作用

    2021-04-23 17:17:51
    什么是反射反射原理java类的执行需要经历以下过程编译:.java文件编译后生成.class字节码文件加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其...
  • java反射底层实现原理

    2021-02-12 19:27:06
    1. 什么是反射?1.1. 问题11.对象有编译类型和运行类型Object obj = new java.util.Date();编译类型:Object运行类型(其实就是obj对象真实的类型):java.util.Date需求:根据对象obj调用Date类中的一个方法,...
  • 9.1 概念JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;public、protected、private。OO(面向对象),private私有的,不能访问...
  • Java中的反射机制的原理和用途是什么?java反射机制的实现原理java反射机制有什么用,具体举例说明增加程序的灵活性。 如struts中。请CSS布局HTML小编今天和大家分享的派发控制。 当请CSS布局HTML小编今天和大家分享...
  • java中的反射原理,为什么要使用反射以及反射使用场景     什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;...
  • Java 反射原理

    2021-03-22 13:49:48
    Java反射的实现Java层面来说用传统的OOP思想来说,任何一个你写好的且编译过的生成的Class文件,在被类加载器加载后,都会对应有一个java.lang.Class 这个类的实例。JVM层面来说首先 Class 文件是一组以8位字节为...
  • 和注解的配合使用原理反射优缺点调试查看Class类获取Class实例的方式1. 通过对象获得2. 通过Class.forname获得3. 通过类名.class获得4.基本内置类型的包装类用Type属性获得5. 一个Class实例通过.getSuperclass()...
  • Java反射机制使用的还是比较广泛的,系统的灵活性、可扩展性大都都是通过反射等方式来加载外部插件,使得系统与插件解耦的同时,增加了功能。但是很多人都只是会用,却是不知道它的实现机制,今天就由我来带大家...
  • Java反射机制原理

    2021-09-11 20:31:55
    本篇文章针对Java反射基本原理做一些探究,以期对Java反射机制有较为清晰的认识。由于网上的源码级的博客很多,本篇文章主要总结思想,故不会大篇幅的探究源码,但作者的认知是建立在对源码的探究之上的,所以有...
  • 写在前面: Java反射, 这个东西百度就会出来相关概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息...
  • Java反射的作用和原理

    2021-05-24 15:47:41
    Java反射的作用和原理 概念:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能...
  • java--反射原理及操作

    2021-02-27 11:29:45
    1、反射原理反射具体操作15、反射原理(********理解********)* 应用在一些通用性比较高的代码 中* 后面学到的框架,大多数都是使用反射来实现的* 在框架开发中,都是基于配置文件开发** 在配置文件中配置了类,...
  • Java分享注解与反射原理说明,首先注解若想发挥更大作用,还需借助反射机制之力。通过反射,可以取得一个方法上声明的注解的全部内容。一般有两种需求:1、取得方法中全部的注解,通过调用getAnnotations来实现。2、...
  • Java--反射机制原理、几种Class获取方式及应用场景

    万次阅读 多人点赞 2021-08-22 11:26:31
    1.1 反射原理1.2 举例说明二、Java反射机制中获取Class的三种方式及区别?2.1 三种方式及区别2.2 代码演示区别三、Java反射机制的应用场景有哪些?3.1 应用场景3.2 应用场景实现3.2.1 简单工厂模式3.2.2 简单工厂...
  • Java反射原理(1)

    2021-03-10 09:37:40
    反射观点Java反射就是行使加载到jvm中的.class文件来举行操作的。.class文件中包罗java类的所有信息,当你不知道某个类详细信息时,可以使用反射获取class,然后举行种种操作。在运行状态中,对于随便一个类,通过...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 118,616
精华内容 47,446
关键字:

反射java原理

java 订阅