专栏首页丑胖侠面试:说说Java反射中获取Class对象三种方式的区别?

面试:说说Java反射中获取Class对象三种方式的区别?

在上篇文章《一篇文章全面了解Java反射机制》中我们学习了Java反射机制的基本使用,留心的朋友可能已经注意到了,在文中提到了三种获取Class对象的方法。

如果面试中涉及到Java反射,那么遇到该面试题的概率将大大增加。

以下三种获取Class对象的方式有什么不同? 1、new Object().getClass 2、Object.class 3、 Class.forName(“java.util.String”)

本篇文章就通过实例带大家来了解一下这三种获取Class对象的区别。示例基于JDK8。

实例演示场景一

为了更好的演示,我们先创建一个对象Person,对象内部定义了一些静态的方法。

public class Person {

	static {
		System.out.println("Person:静态代码块");
	}

	{
		System.out.println("Person:动态代码块");
	}

	public Person(){
		System.out.println("Person:构造方法");
	}
}

在Person对象中分别定义了:静态代码块、动态代码块、构造方法。

针对上面的实例,我们构建了三个单元测试的场景,对应代码如下:

public class GetClassTest {

	@Test
	public void test1(){
		Class<?> clz = Person.class;
	}

	@Test
	public void test2() throws ClassNotFoundException {
		Class<?> clz = Class.forName("com.choupangxia.reflect.Person");
	}

	@Test
	public void test3() {
		Class<?> clz = new Person().getClass();
	}
}

分别执行三个单元测试发现,第一个单元测试没打印任何内容;第二个单元测试打印了“静态方法”中的内容;第三个单元测试打印出了全部内容:

Person:静态代码块
Person:动态代码块
Person:构造方法

也就是说通过Person.class的方法获取对象的Class对象,根本不会调用对象中任何的代码块或代码。而Class.forName()会调用静态代码块的内容。

而第三种方式打印所有内容的原因很显然,就因为要先实例化对象。

实例演示场景二

下面再组合一下这三种方式,看看一些其他的效果。

首先,依次调用三个获取Class对象的方法:

@Test
public void test4() throws ClassNotFoundException {
	Class<?> clz = Person.class;
	System.out.println("---------------");
	clz = Class.forName("com.choupangxia.reflect.Person");
	System.out.println("---------------");
	clz = new Person().getClass();
}

test4打印日志如下:

---------------
Person:静态代码块
---------------
Person:动态代码块
Person:构造方法

通过日志说明,Class.forName()方法执行过静态代码块之后,new Person().getClass()就不再会执行同样的静态代码块了。这也证明静态代码块只会被初始化一次。

再调整组合第二种场景:

@Test
public void test5() throws ClassNotFoundException {
	Class<?> clz = new Person().getClass();
	System.out.println("---------------");
	clz = Class.forName("com.choupangxia.reflect.Person");
}

test5打印日志如下:

Person:静态代码块
Person:动态代码块
Person:构造方法
---------------

同样只打印一次静态代码块的操作。再次证明类中的静态代码块只会被初始化一次。

实例演示场景三

这里,我们比较一下三种形式获得的Class对象是否是相同的。测试代码如下:

@Test
public void test6() throws ClassNotFoundException {
	Class<?> clz1 = Person.class;
	Class<?> clz2 = Class.forName("com.choupangxia.reflect.Person");
	Class<?> clz3 = new Person().getClass();

	System.out.println(clz1 == clz2);
	System.out.println(clz2 == clz3);
}

注意,上面我们使用的是等号,也就是说比较的是引用。猜猜打印的结果?

true
true

三种形式获得的Class对象是同一个对象。这是为什么呢?

这要涉及到类的加载过程,我们知道类加载过程分:加载阶段、连接阶段和初始化阶段。

类的加载阶段是将class文件中的二进制数据读取到内存中,然后将该字节流所代表的静态存储结构转化为方法区中运行时的数据结构,并且在堆内存中生成一个该类的java.lang.class对象,作为方法区数据结构的入口。

类加载阶段的最终产物是堆内存中的class对象,对于同一个Classloader对象,不管某个类被加载多少次,对应堆内存中的class对象始终只有一个。

也就是说无论通过哪种形式来获取Class对象,获得的都是堆内存中对应的Class对象。

回顾三种形式

(1)类名.class:JVM将使用类装载器,将类装入内存(前提是:类还没有装入内存),不做类的初始化工作,返回Class的对象。

(2)Class.forName(“类名字符串”):装入类,并做类的静态初始化,返回Class的对象。

(3)实例对象.getClass():对类进行静态初始化、非静态初始化;返回引用运行时真正所指的对象(子对象的引用会赋给父对象的引用变量中)所属的类的Class的对象。

原文链接:《面试:说说Java反射中获取Class对象三种方式的区别?

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)

    4.4.3 约束(Pattern的一部分) 前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false...

    程序新视界
  • Spring Boot中Controller接收对象列表实现

    注意要提交的页面元素的name值为“rules[1].column”。通过这种形式来指定列表中的第几个元素的具体属性值是什么。

    程序新视界
  • 《Drools7.0.0.Final规则引擎教程》第4章 Query查询之基础

    Query查询 首先,我们先来看一下query的语法结构图: ? Query语法提供了一种查询working memory中符合约束条件的FACT对...

    程序新视界
  • java语言反射的概述以及三种获取字节码文件对应的Class类型的对象的方式

    反射的概述:   JAVA反射机制是在运行状态中,   对于任意一个类,都能够知道这个类的所有属性和方法(动态获取的信息);   对于任意一个对象,...

    黑泽君
  • Vue学习笔记之Vue指令系统介绍

    所谓指令系统,大家可以联想咱们的cmd命令行工具,只要我输入一条正确的指令,系统就开始干活了。

    Jetpropelledsnake21
  • 使用:before选择器给你的Logo添加扫光特效

    在知更鸟大神的网站看到他的Begin主题Logo有扫光特效,看起来还是比较炫的。研究了一下,发现是用:before选择器实现的扫光效果,现在把代码甩出来,觉得好...

    墨渊
  • java之通过反射生成并初始化对象

    java之通过反射生成并初始化对象 在博文 《java之的读取文件大全》 中读取csv文件后,需要自己将csv文件的对象转为自己的DO对象,那么有没有办法我...

    一灰灰blog
  • 业界 | 百度加入Partnership on AI,成为该机构首个中国籍会员

    美国时间 10 月 16 日,Partnership on AI 在最新公告中欢迎首位中国新成员百度加入,并称此次合作是「建立一个真正全球性合作机构的重要一步」...

    机器之心
  • 宏基因组学习笔记2

    metagenomics, 在希腊语中meta意思是超越的。宏基因组研究的目的是通过对菌种(株)的鉴定,获得真实的多样性数据,功能,协作和进化。宏基因组分析的三...

    用户1075469
  • 小心,Android木马工具SpyNote免费啦!远程监听就是这么简单

    只要是做生意,都得讲究价值规律,黑市也不例外。某款产品要是搞打折促销,群众们必然蜂拥而至——要是免费大派送,那一传十十传百的速度又怎是门庭若市可形容! 最近Pa...

    FB客服

扫码关注云+社区

领取腾讯云代金券