美文网首页
Java反射中获取Class对象三种方式的区别

Java反射中获取Class对象三种方式的区别

作者: 倚仗听江 | 来源:发表于2020-09-05 14:44 被阅读0次

Java反射中获取Class有三种方式:

  • new Object().getClass
  • Object.class
  • Class.forName("com.sherlock.demo")

以下就详细的讲讲这三种方式的区别
首先我们先定义一个Demo类,其中定义了静态代码块、动态代码块和构造函数

public class Demo {
    static {
        System.out.println("Demo:静态代码块");
    }
    {
        System.out.println("Demo:动态代码块");
    }
    public Demo(){
        System.out.println("Demo:构造方法");
    }
}

分别对这三种场景进行测试

public class Test {
    @org.junit.jupiter.api.Test
    public void test1(){
        Class<?> clz = Demo.class;
    }

    @org.junit.jupiter.api.Test
    public void test2() throws ClassNotFoundException {
        Class<?> clz = Class.forName("com.sherlock.Demo");
    }
    @org.junit.jupiter.api.Test
    public void test3() {
        Class<?> clz = new Demo().getClass();
    }
}
  • 第一种方式下,没有任何的输出,说明通过Demo.class获取对象的Class对象,不会调用任何的代码块和代码。
  • 第二种方式下,会打印:Demo:静态代码块,说明在这种方式下会调用静态代码块的内容。
  • 第三种方式下,会打印:Demo:静态代码块
    Demo:动态代码块
    Demo:构造方法
    也就是说,在这种方式下,因为要先实例化对象,所以会打印全部的内容。

接下来我们同时使用这三种方式

@org.junit.jupiter.api.Test
    public void test4() throws ClassNotFoundException {
        Class<?> clz = Demo.class;
        System.out.println("---------------");
        clz = Class.forName("com.sherlock.Demo");
        System.out.println("---------------");
        clz = new Demo().getClass();
    }

打印结果


打印结果.jpg

使用Demo.class还是和上面一样,不会调用任何的代码或代码块。使用Class.forName("com.sherlock.Demo")会调用静态代码块。但是在使用new Demo().getClass()时,却没有再次调用静态代码块,说明了静态代码块只会被初始化一次。

再来比较一下这三种情况下获得的对象是不是同一个

@org.junit.jupiter.api.Test
    public void test6() throws ClassNotFoundException {
        Class<?> clz1 = Demo.class;
        Class<?> clz2 = Class.forName("com.sherlock.Demo");
        Class<?> clz3 = new Demo().getClass();
        System.out.println(clz1 == clz2);
        System.out.println(clz2 == clz3);
    }

可以发现比较的结果都是true,说明获取的是同一个对象。这是因为对于同一个Classloader对象,不管某个类被加载多少次,对应堆内存中的class对象始终只有一个。也就是说无论通过哪种形式来获取Class对象,获得的都是堆内存中对应的Class对象

总结一下:
(1)类名.class:JVM将使用类装载器,将类装入内存(前提是:类还没有装入内存),不做类的初始化工作,返回Class的对象。
(2)Class.forName(“类的全限定名”):装入类,并做类的静态初始化,返回Class的对象。
(3)实例对象.getClass():对类进行静态初始化、非静态初始化;返回引用运行时真正所指的对象(子对象的引用会赋给父对象的引用变量中)所属的类的Class的对象。

原文链接:https://www.choupangxia.com/2020/03/27/java-reflect-class/

相关文章

  • Java反射中获取Class对象三种方式的区别

    Java反射中获取Class有三种方式: new Object().getClass Object.class C...

  • java反射知识点记录

    获取反射中的class对象在反射中,要获取一个类或调用一个类的方法,首先需要获取到该类的class对象。在java...

  • Java获取Class对象的方式和实例化对象的方式

    Java获取Class对象的方式和实例化对象的方式 获取Class对象的方式 实例化对象的方式

  • java(代理和反射)

    反射和代理 反射 Class类和java.lang.reflect包 获取Class对象jdk提供了三种方式获取一...

  • Java中反射的简单使用

    1、获取Class对象 获取Class对象有三种方式,如下: 2、获取属性 3、获取构造方法 4、实利化对象 5、...

  • 反射

    获取class的三种方式 1、根据对象获取 对象.getClass 2、根据类获取 类名.class 3、根据全类...

  • java基础-反射

    知识点 反射的基本概念 反射中class类的获取 反射中field类属性的获取 反射中method类方法的获取 反...

  • 关于反射

    1. 三种获取类对象的方式 三种获取类对象的方式,内存中一个类只会有一个class对象。 2.哪些类有Class ...

  • 反射

    一、 获取Class对象的三种方式: 二、 Java里面反射出来的类 三、 Constructor常用方法: 四、...

  • 反射

    反射 class 获取class字节码对象的三种方式: //1、通过类.class Class cla...

网友评论

      本文标题:Java反射中获取Class对象三种方式的区别

      本文链接:https://www.haomeiwen.com/subject/ppffektx.html