类加载与Class对象

java零基础入门-高级特性篇(十四)  类加载与反射 1

初学者有时候在做练习的时候,可能会碰到一个十分诡异的问题。今天老师讲到了String字符串,好开心,打开eclipse开始写代码,然后一顿操作,只见双手在键盘上飞驰,行云流水般写出如下代码,嘴角露出一丝微笑,String也不过如此嘛。

报错

等等,咋报错了?这是个什么情况?哪里有错?为什么连个String类型都不给我用了?为什么!!!接下来轻则怀疑自己智商,重则自暴自弃,从此放弃走上码农之路。

其实大家仔细一看,哦~原来是类的名字有问题啊,怎么能定义一个叫String的类呢,这样写肯定报错呀。但请各位再仔细想一想,为什么就不能定义一个叫String的类呢?恐怕能说出其中原因的同学并不多。

类加载器与双亲委派模型

首先来回忆一下前面的知识。编写完java文件后,jvm是不能直接运行java文件的,首先要将java文件编译成class文件以后,jvm再把class文件加载到内存中,创建一个Class对象,这时候才可以使用这个类。加载这个动作,就是由类加载器完成的。在jvm中有三个内置类加载器,Bootstrap ClassLoader,Extension ClassLoader,Application ClassLoader。

Bootstrap ClassLoader:启动类加载器,用于加载java核心库jre/lib/rt.jar

Extension ClassLoader:扩展类加载器,用于加载java扩展库jre/ext/*.jar

Application ClassLoader:应用程序类加载器,自己写的代码都是使用这个加载器来加载的

先来看看这几个加载器的工作流程

工作过程

这个类的加载过程有一个更加专业的名字,叫做双亲委派模型。这个模型名字看名字不好理解,来想象一下下面这个场景。小明一家人一起吃饭,看到大鸡腿就想吃,但是中华文明优良传统告诉他,得先问问爸爸,这个大鸡腿我能吃吗?然后爸爸又看看爷爷,问爷爷要吃吗?爷爷说还是给小明吃吧,这时候爸爸再告诉小明,你可以吃了。爸爸和爷爷是双亲,能不能吃要先看上面,如果恰好爷爷也想吃,小明也只能干瞪眼了。

再来看这个双亲委派模型,在加载类的时候,应用程序类加载器不会直接去加载它,它先要问它的父类加载器,它的父类加载器再去问爷类加载器,爷类加载器一看,不该我管,丢给父类,父类一看,也不是我管,最后丢回来给应用程序类加载器。

再来看看上面那个String的例子,为什么会报错。java本身有一个String的类型,String在哪?

java.lang.String

注意String最上面的jar包,Bootstrap ClassLoader的管辖范围就是这个jar包,现在知道程序报错的原因了没?根据类的加载流程,我们希望得到的String是应该被启动类加载器加载的String,如果String的类路径是java.lang.String,就是我们想要的String。但是上个例子里面,我们自定义了一个String,它的类路径不是java.lang.String,所以他不会被启动类加载器加载,而是最后被应用程序类加载器加载,所以它并不是我们想要的那个String,不是那个可以用字符串赋值的类型String,这时候将一个字符串赋值给这个“String”,在编译的时候就会出错,因为我们自定义的String不具备这个接收字符串赋值的功能。

Class类型

上面说过,jvm把class文件加载到内存中时,会创建一个Class对象。这个Class对象是什么呢?类不是用class定义的么,怎么还有一个Class?别晕,现在就来详细说说Class是干什么的。

先从Class存在的意义来说。类是一类事物的描述,类包含了这类事物的信息,比如车这个类,包含了车的类型,用途,行为信息,可以在路上跑。鱼这个类,包含了鱼的种类,名称,行为信息,可以在水里游。

类的属性和行为

从上图可以看到,用属性和行为可以描述一类事物。那么“类”这个事物,是否也可以被描述呢?答案是肯定的,Class类就是用来描述类的信息的。Class也是一种类型,它专门用来描述类的特征。

类类型

车这个类可以用名称,类型,行为来描述。类这个类可以用属性,行为来描述,所有的类都可以有属性,都可以有行为。可以将Class类看做是普通类型的更高层抽象,用来描述普通类如何构成,包含内容等信息。

再从类的加载和对象创建来说。每写完一个类文件,首先会被编译成.class文件,然后在运行时,这个.class文件会被加载到jvm中,如果是第一次加载这个类,那么会同时生成这个类对应的Class对象。当使用new关键字创建类的对象的时候,会首先去这个类对应的Class对象获取该类的信息,然后创建对象,所以可以将Class对象看做是类的模板,同一个类的对象创建都使用这个模板。类创建的对象可以有很多,但是模板只有一份,也就是说每个类对应的Class对象只有一个。

关系

java文件被编译加载后创建Class对象,当这个java文件的类需要创建对象的时候,也就是使用new关键字创建对象的时候,会去获取那个已经被创建好的Class对象中的信息。这里要注意一个重点,获取Class对象信息的时候是运行时,只有在运行时才能通过Class获取类的信息。

获取Class对象

既然Class对象包含这么多信息,那么在程序中如何获取Class对象?获取Class的方法有三种:

1.Class.forName("类名"); 通过类名字符串获取Class对象。

2.通过类的对象调用getClass() 获取该类型的Class对象

3.通过类型直接获取Class对象

获取Class对象

先看第一种方法,通过类型的全限定名获取Class对象。通过这种方式可以直接使用一个字符串来获取Class对象,这种方式使用起来比较灵活,当需要对类型进行配置的时候,可以将对象的全限定名写入到配置文件中,这样就可以在不修改代码的情况下,通过修改配置的方式来改变创建对象的类型。需要注意的是,通过Class.forName()方法获取的对象是无法确定类型的,所以使用无限制泛型通配符。

第二种方法,是通过对象的实例的getClass()方法来获取Class对象,这种方式要先创建类型的对象,再根据创建的对象来获取Class对象。由于根据已知类型的对象获取的Class,所以这个Class对象的类型可以是User或其子类。

第三种方法,直接根据类型获取Class对象,这种方式最直接,连方法都不用调用,直接获取Class对象,速度最快效率最高。一般情况使用这种方法获取Class对象最为普遍。

最后要注意的一点是,同一个类只会有一个Class对象,上例中第二种和第三种方法获取到Class对象后,将获取到的对象与第一种方法获取到的Class对象进行地址比较,结果都是true。可以说明,不管用哪种方法获取Class对象,都只会获取到同一个并且是该类唯一一个Class对象。


现在已经获取到Class对象了,那么该如何使用它呢?前面说过,Class对象有类里面所有的信息,所以可以通过Class获取到类里面所有的构造器,方法,成员变量等等所有的信息。

获取类信息

Class对象可以获取到所有信息,上图只是一个普通的类,如果获取到ClassInfoDemo这个类对应的Class对象,就可以通过调用这个对象的方法获取如上图中包,成员变量,构造器,方法等信息。如果类还有其他信息比如注解,实现接口方法,内部类,外部类等等信息,都可以通过Class对象的对应方法获取,可见Class是一个功能非常强大的类。

讲了半天类的加载和Class对象,这些知识点有什么用?这都是为了接下来登场的知识点-反射打好基础,反射技术十分重要,在各大框架中被频繁的使用,所以在学习的过程中,了解反射的意义对后续框架的学习有很大的帮助。

本文为了方便理解,隐藏了部分类加载中的细节,如需深入了解,请自行查阅相关资料。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容