最近一段时间,对于 java 的反射比较感兴趣,于是打算通过深入学习来更好的了解反射的实现机制。于是开始查阅有关反射的博文,但是在学习的过程中,发现 Class 类始终伴随着反射出现。因为多少接触过 Class 类,所以有关反射的代码还是能看懂的,不会影响我学习反射的知识,本就可以直接略过。

但是仔细一想,学习是一个主动的过程,要积极的去解决每一个小的问题,争取在求知过程中不留存疑惑,否则到最后会发现因为这些小问题的存在,使得自己的理解始终停在“知其然,不知所以然”的层面。既然接触到了 Class 类,就应该顺带消化了,这样的才能学到更多的东西。

后续我会和大家分享我在学习反射时的一些心得,在此之前,先分享一下我学习 Class 类的一些体会哈。此次分享没有太多高深的知识,但是还是觉得只要您认真的看完本文,多少会有收获的,哪怕是巩固一下也不错,嘿嘿 : )

面向对象

我们都知道,java 是一门面向对象的语言。在面向对象的世界里,万事万物皆对象,除了静态成员(因为静态成员属于某个类,而不是对象)和普通数据类型。

在面向对象的语言中,我们擅长将现实世界中的一个实际存在的事物抽象并封装成一个类,并在类中添加相应的成员变量(属性)和方法,然后我们就可以创建该类的对象,该对象持有属于自己的成员变量和方法。

既然万事万物皆对象,那么我们的类是不是对象呢?是的,我们写的每一个类都是对象,是 java.lang.Class 类的对象。也就是说,每一个类既有自己的对象,同时也是 Class 类的对象。那么,该如何表示 Class 类的对象呢,让我们接着往下看,以进一步了解 Class 类。

java.lang.Class 类

初识 Class 类

很遗憾直到现在我才认识到 Class 的意义,不敢说这次接触就彻底弄懂了 Class 类,但至少目前所理解的内容可以帮助我更好的分析其他问题了。

都说学习技术最好的方法就是查看源码和官方 API ,那么这次我也这么来,虽然我技术一般,但是格调还是要跟上的!我发现了一篇比较好的从源码角度分析 Class 类的博客,在这里推荐给大家,感兴趣的可以跟着这篇文章把 Class 类的源码过一遍,一定会有收获的。当然,您现在不看也没关系,因为推荐的博客中只有一点是我接下来要强调的,我会在后面给大家概括出来。点我跳转

先来看看 Class 类的构造方法(有删减):

 /** Private constructor. * Only the Java Virtual Machine* creates Class objects.*/private Class(ClassLoader loader) {classLoader = loader;}

根据注释可知,Class 类的构造方法是私有的,只有 Java 虚拟机可以创建该类的对象,因此我们无法在代码中显式地声明一个 Class 对象。这就是我要强调的内容,其对于后面内容的理解十分重要。

Class 类与其他类的关系

由类或类对象得到 Class 类的对象

自定义一个类 MyClass,并声明该类的对象:

class MyClass{}MyClass mClass1 = new MyClass();

在上面说过,Class 类的构造方法是私有的,只有 java 虚拟机可以调用该方法创建该类的对象。也就是说我们无法像定义普通类对象一样,通过 new 直接创建 Class 类的对象。

但是,我们依然可以通过其他方式得到 Class 类的对象

  1. 通过类的静态成员表示。每个类都有一个隐含的静态成员class,表示如下:

    Class c1 = MyClass.class;
    
  2. 通过类对象的 getClass() 方法。由1不难理解,既然存在静态变量,那么通过对象的 getter 方法,就可以获取静态成员class:

    Class c2 = mClass1.getClass();
    
  3. 通过 Class 类的静态方法 forName() 方法获取 Class 的对象。区别于通过 new 创建对象(编译时静态加载),在开发时如果我们需要动态加载我们的功能模块,该方法可以帮助我们实现在程序运行时类的动态加载。

    try {//注意,forName()需要传入类的全路径//如果当前类与参数类在同一包下即可省略包名mClass = Class.forName("custom.OtherClass");} catch (ClassNotFoundException e) {e.printStackTrace();}
    

如果我们的程序中没有 OtherClass 这个类,使用 Class.forName() 动态加载时,在程序编译时刻是不会报错的,只有在运行时刻检测到没有该类才会出错。

类的动态加载静态加载是 Java 中一个重要的知识点,但因为我们开发时通常都使用 IDE, 其帮助我们自动实现了程序的编译和运行,使得我们常常忽略了程序的编译时和运行时状态。说着说着,我发现这块我有必要再写一篇博客记录一下,今天就先不讨论了。

由 Class 类的对象得到类的对象

我们可以通过类或类对象得到 Class 类的对象,反过来,我们也可以由 Class 类的对象得到类的对象:

MyClass mClass2 = (MyClass)c2.newInstance();

需要提醒您的是:c2.newInstance() 需要调用 MyClass 类的无参构造方法!如果 MyClass 类中存在显示的有参构造方法,会覆盖默认的无参构造方法,同时又没有显示的声明无参构造方法,那么执行这段代码时会直接导致程序Crash掉。下面为大家演示一下:

示例代码,请看注释:

/*** Created by Mr Rui on 2016/5/1.*/
public class TestDemo {public static void main(String args[]){//得到 Class 对象 mClassClass mClass = MyClass.class;try {// 由 mClass 实例化 MyClass 的对象,// 需要调用 MyClass 的无参构造方法MyClass mMyClass = (MyClass) mClass.newInstance();} catch (Exception e) {e.printStackTrace();}}
}class MyClass{//有参构造方法,会覆盖默认的无参构造方法public MyClass(String s){}
}

程序异常:

java.lang.InstantiationException: MyClassat java.lang.Class.newInstance(Class.java:427)at TestDemo.main(TestDemo.java:12)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:497)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NoSuchMethodException: MyClass.<init>()at java.lang.Class.getConstructor0(Class.java:3082)at java.lang.Class.newInstance(Class.java:412)... 6 more

解决办法就是在 MyClass 中的显示的添加一个 无参构造方法,就不再提供示例了。

针对这一点,相信有许多人在使用第三方框架或者开源库时,遇到过因为在类中添加了带参数的构造方法而导致程序出错的情况!针对这个,我的理解是:有些框架是基于反射实现的,它根据我们传入的类对象,使用其 newInstance() 方法获取 Class 对象,进而进行后续的反射操作(不在本文的讨论范围)。可是因为我们无意覆盖了默认的无参构造方法,导致程序无法正常获取 Class 对象,所以就出错了。说到这儿,您应该能理解其中缘由了吧!

这次分享的内容比较少,归结起来就是如何获取 Class 类的对象,以及如何由 Class 对象得到类对象。至于如何使用 Class 对象进行反射操作,如何实现程序运行时动态加载类,在后面的分享中会继续向大家介绍的。

我将所理解知识梳理并整理出来,一方面供大家参考交流,另一方面因为我也处在学习的阶段,希望能得到更多人的指导。如果文中有任何错误或遗漏的地方,还望您给予指正,我会积极完善!

Java 反射基础(上)


扫描下方二维码,关注我的公众号,及时获取最新文章推送!

浅谈 Java 中的 Class 类相关推荐

  1. 浅谈Java中的BigInteger类

    在Java中,由于CPU原生提供的整型数据最大范围是64位的long型整数 那么如果我们在使用的时候数据超过了long型整数的范围该怎么办,这个时候,我们就需要用到Java中的一个类:java.mat ...

  2. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  3. 浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  4. java中修饰常量的事_浅谈java中的声明常量为什么要用static修饰

    今天定义一个类常量,想着也只有这个类可以用到,就没用static关键字修饰.结果sonar代码检查提示: Rename this field "PERSON_TYPE_USER" ...

  5. 浅谈JAVA中如何利用socket进行网络编程(二)

    转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...

  6. file相对路径java_浅谈java 中文件的读取File、以及相对路径的问题

    一.对于java项目中文件的读取 1.使用system 或是 系统的properties对象 ①直接是使用 string relativelypath=system.getproperty(" ...

  7. java中的强制类型转换注意事项_浅谈Java中强制类型转换的问题

    为了更好的理解我们先看下面的例子: package com.yonyou.test; import java.util.ArrayList; import java.util.Iterator; im ...

  8. 浅谈Java中的栈和堆

    人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...

  9. java布尔类型比较器_浅谈Java中几种常见的比较器的实现方法

    在java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题. 通常对象之间的比较可以从两个方面去看: 第一个方面:对象的地址是否一样,也就是是否引用自同一个对象.这种方式可以直接使用& ...

最新文章

  1. Win32汇编数据对齐相关的伪指令(ALIGN、EVEN、ORG)
  2. 我用nagios-check_http check Checker
  3. FastDFS配置nginx插件访问图片
  4. PMCAFF|百度客户端产品:高效开发客户端产品的正确姿势
  5. C语言中如何使用宏连接多个字符串(#和##的用法)
  6. python短时傅里叶变换_短时傅里叶变换的python实现
  7. python字符串_python的字符串怎么拼接
  8. Day4:html和css
  9. Android三种左右滑动效果 手势识别(转)
  10. L2-001 城市间紧急救援 (25 point(s))
  11. zookeeper启动失败解决方法
  12. 【支付】银行卡收单业务
  13. 搜狗输入法 linux 卸载,ubuntu彻底卸载搜狗拼音输入法
  14. Vue 事件绑定与解绑
  15. c语言计算利息答案是0.0,ACCP北大青鸟4.0 程序逻辑和C语言实现课本后的习题和上机题目,怎么做?...
  16. Warshall沃舍尔算法
  17. 浅谈无线路由器自动掉线解决办法
  18. android listview网络图片,Android ListView从网络获取图片及文字显示
  19. 单片机定时器计数原理
  20. 珞石(ROKAE)机械手简单的编程

热门文章

  1. Python中的类变量和成员变量
  2. 使用Tickeys寻找打字音效
  3. java中jcl,spring-jcl 日志源码分析
  4. 年中总结 | 经历过求职春招刷题备考疫情洪水的一届毕业预备军真的太太太难啦!
  5. 最短工期 数据结构实现
  6. NURBS求取basis函数的代码
  7. 塔望·食业研究丨方便速食行业市场主要竞争品牌分析及研究
  8. GTX/GTH QPLL CPLL学习之Aurora
  9. Win7资源管理器打开ftp站点自动跳转浏览器解决方法
  10. Flash动画学习指南七:运动路径