1.介绍

  getClass()介绍

  java是面向对象语言,即万物皆对象,所有的对象都直接或间接继承自Object类;

  Object类中有getClass()方法,通过这个方法就可以获得一个实例对象在内存中的实际类型。

  类名.class介绍

  通过对类名的引用取得在内存中该类型的实际类型。

  Class.forName("包名xx.类名xx")介绍

  通过"包名+类名"的方式同样可以取得在内存中该类型的实际类型。

2.区别

  第一,类的加载方式不同

  Class.forName()属于动态加载类,在代码运行时加载指定类;

  Class.class属于静态加载类,在代码编译时加载指定类;

  object.getClass()取决于对象的产生方式:

  既可以是静态加载类(通过new创建的对象),也可以是动态加载类(通过Class.forName(xx.xx)创建的对象,对象可能不存在)。

Class.forName("bbb").newInstance().getClass();

  第二,Class对象的创建方式不同

   Class.forName()

  运行阶段:JVM使用类装载器, 将类装入内存中,并对类进行初始化(静态代码块、非静态代码块、构造函数调用及静态变量);

  最后返回Class的对象。

  类名.class

  编译阶段:JVM使用类装载器, 将类装入内存中,并对类进行初始化操作;

  最后返回Class的对象。

  实例对象.getClass()

  当调用getClass()方法时,该对象的类已经被加载到内存中并且完成了初始化操作;

  直接返回Class的对象,没有其它操作。

  第三,对象与类的关系不同

  通过类创建对象:

  Class.forName(xxx.xx.xx)和Class.class返回的是一个类,调用newInstance()后才创建一个对象;

// 获取类
Class<String> c = String.class;
// 通过类创建对象
String s = c.newInstance();

  通过对象获取类:

  object.getClass();

// 获取类
Class<String> c = String.class;
// 通过类创建对象
String s = c.newInstance();
// 通过对象获取类
Class<? extends String> c2 = s.getClass();

3.测试

  公用代码

/**
* class类加载
* @explain
* @author Marydon
* @creationTime 2018年10月19日上午9:26:29
* @version 1.0
* @since
* @email marydon20170307@163.com
*/
public class ClassLoader2 { /**
* 构造函数
* @explain 在类每次被实例化时执行
*/
public ClassLoader2() {
System.out.println("--------调用构造函数--------");
} /**
* 静态的参数初始化
* @explain 在类初次被加载到内存中时执行
*/
static {
System.out.println("--------执行静态代码块--------");
} /**
* 非静态的参数初始化
* @explain 在类每次被实例化时执行
*/
{
System.out.println("--------执行非静态代码块--------");
} }

  注意:

  类名一定不能是ClassLoader.java,因为已经存在java.lang.ClassLoader了,如果还命名为ClassLoder,会影响测试结果;
  起初自己发现了新大陆,原来是个坑,空欢喜一场!

/**
* class类加载测试
* @explain
* @author Marydon
* @creationTime 2018年10月19日下午3:44:32
* @version 1.0
* @since
* @email marydon20170307@163.com
*/
public class TestClassLoader2 {
static {
System.out.println("执行TestClassLoader2.class初始化操作!");
} public static void main(String[] args) throws ClassNotFoundException{ }
}

  测试:类.class

// 测试1:类.class
Class<ClassLoader2> c = ClassLoader2.class;
System.out.println(c);

  测试结果:ClassLoader2.class在编译时已经加载到了内存中。

  判断依据:静态代码块并没有执行!

  测试:objet.getClass()

  方式一:使用静态加载类创建对象

Object cl2 = new ClassLoader2();
System.out.println(cl2.getClass());

  测试结果:

  方式二:使用动态加载类创建对象

System.out.println(Class.forName("test.ClassLoader2").newInstance().getClass());

  说明:

  无论是在通过动态加载类还是静态加载类创建的ClassLoader2类的对象时,ClassLoader2类都会被重新加载到内存当中,

  所以当调用.getClass()方法时,并不会执行任何类的初始化操作。

  测试:Class.forName("包名.类名")

public static void main(String[] args) throws ClassNotFoundException {
// 测试3:Class.forName()
Class<?> c3 = Class.forName("test.ClassLoader2");
System.out.println(c3);
}

  测试结果:ClassLoader2.class在运行时被加载到内存中。

  判断依据:静态代码块执行!

  类比较(判断是否时同一class类型)

  在上面的main方法中添加

System.out.println("--------类比较--------");
System.out.println(c.equals(cl2.getClass()));
System.out.println(c.equals(c3));

  测试结果:

  证实:非静态代码块与构造函数,每次实例化都会被执行。(与文章主题无关)

  在上面的main方法中添加

System.out.println("第二次实例化ClassLoader2");
ClassLoader2 cl3 = new ClassLoader2();

  测试结果:  

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 

java 类名.class、object.getClass()和Class.forName()的区别 精析的更多相关文章

  1. 详解Java中的Object.getClass()方法

    详解Object.getClass()方法,这个方法的返回值是Class类型,Class c = obj.getClass(); 通过对象c,我们可以获取该对象的所有成员方法,每个成员方法都是一个Me ...

  2. Java类名.class和getClass()区别

    区别 类名.class叫做“类字面量”,因class是关键字, 所以类名.class编译时确定. getclass()运行时根据实际实例确定,getClass()是动态而且是final的. Strin ...

  3. Java中泛型Class<T>、T与Class<?>、 Object类和Class类、 object.getClass()和Object.class

    一.区别 单独的T 代表一个类型(表现形式是一个类名而已) ,而 Class<T>代表这个类型所对应的类(又可以称做类实例.类类型.字节码文件), Class<?>表示类型不确 ...

  4. 关于java反射里的.class、.getClass()、Class.Forname()

    博主在研究java反射这一章节时,曾被三个方法困扰多时,.class..getClass().Class.Forname(),先上代码 这是类A package cn.yonyong.net.tcp. ...

  5. Java unserialize serialized Object(AnnotationInvocationHandler、ysoserial) In readObject() LeadTo InvokerTransformer(Evil MethodName/Args)

    Java unserialize serialized Object(AnnotationInvocationHandler.ysoserial) In readObject() LeadTo Tra ...

  6. Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现   反射的过程如下:     第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...

  7. Java Class 与 Object

    平时看代码时,总是碰到这些即熟悉又陌生的名次,每天都与他们相见,但见面后又似曾没有任何的交集,所以今天我就来认识下这两个江湖侠客的背景: CLASS 在Java中,每个class都有一个相应的Clas ...

  8. java中instanceof和getClass()的作用

    初学者难免有点混淆java中instanceof和getClass()的作用,  下面就来一一讲解. 父类A: class A { } 子类B: class B extends A { }  构造对象 ...

  9. Java常见对象Object类中的个别方法

    Java常见对象Object类 public int hashCode() : 返回该对象的哈希码值. 注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值.你可以理解成 ...

随机推荐

  1. oracle之表空间(tablespace)、方案(schema)、段(segment)、区(extent)、块(block)

    数据文件和日志文件是数据库中最关键的文件.它们是数据存储的地方.每一个数据库至少有一个与之相关的数据文件,通常情况下不仅仅一个,有非常多.数据在数据文件里是怎样组织的?要了解这些内容我们首先必须理解什 ...

  2. Android下setLatestEventInfo警告、Handler警告、SimpleDateFormat警告

    正 文: 今天飘易在做Android 4.4.2下的APP开发时,使用了Notification下的setLatestEventInfo()方法时,Eclipse却提示:“ 不建议使用类型 Notif ...

  3. Android中UI设计的一些技巧!!!

    出处:http://blog.csdn.net/android_tutor/article/details/5995759 大家好,今天给大家分享的是Android中UI设计的一些技巧,本节内容主要有 ...

  4. MSI failed, 不能卸载VMware

    解决方法; http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&ext ...

  5. JS动态改变select选择变更option的index值

    document.getElementById("louyuming").options[0].selected=true; function jsSelectIsExitItem ...

  6. MAC之tar解压与压缩打包命令

    tar [-cxtzjvfpPN] 文件与目录 ....参数:-c :建立一个压缩文件的参数指令(create 的意思):-x :解开一个压缩文件的参数指令!-t :查看 tarfile 里面的文件! ...

  7. Git 学习(四)操作修改和版本穿梭

    Git 学习(四)操作修改和版本穿梭 之前的章节,已介绍了本地Git库创建.暂存区增.删.改,以及提交版本库:可回顾下命令操作: git add 和 git commit. 光有之前章节的操作,Git ...

  8. Endianess(字节次序)简介

    1. 基础 在解释Endianess前,需要先明白几个基础定义 1) 数据的高位与低位是什么 以1001001为例,则从左边算起是 高位 -> 低位, 简而言之就是左边是高位,右边是低位 而内存 ...

  9. 我所遭遇过的游戏中间件--PhysX

    我所遭遇过的游戏中间件--PhysX PhysX现在是Nvidia的物理中间件.其特点是简练且功能强大.当我最初拿到PHYSX的SDK时,就发现这个物理中间件比Havok要小很多,但该有的功能都有,甚 ...

  10. Android UI-仿微信底部导航栏布局

    现在App基本的标配除了侧滑菜单,还有一个就是底部导航栏,常见的聊天工具QQ,微信,购物App都有底部导航栏,用户可以随便切换看不同的内容,说是情怀也好,用户体验也罢.我们开发的主要的还是讲的是如何如 ...