java.lang.Class类详解

java.lang.Class类详解1.Class类与类的关系 Java程序运行时,系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。说白了,Class类对象就是封装了一个类的类型信息,可以通过该对象操作其对应的类,即发射机制。

大家好,又见面了,我是你们的朋友全栈君。


1.Class 类与类的关系


  Java程序运行时,系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。说白了,Class类对象就是封装了一个类的类型信息,可以通过该对象操作其对应的类,即反射机制。 


  Class 类是在Java语言中定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实现的接口,以及这个类的父类。Class类的对象用于表示当前运行的 Java 应用程序中的类和接口。Class类提取这些类的一些共同特征,比如说这些类都有类名,都有对应的hashcode,可以判断类型属于class、interface、enum还是annotation。这些可以封装成Class类的域,另外可以定义一些方法,比如获取某个方法、获取类型名等等。这样就封装了一个表示类型(type)的类。程序员可以在程序运行时发现和使用类型信息。


  在java中,每个类都有一个相应的Class对象。也就是说,当编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。Class类的每个实例则代表运行中的一个类。


  Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。


  虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。

  基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。


  一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象:

public class ClassTest {
    public static void main(String [] args)throws Exception{
        String str1="abc";
        Class cls1=str1.getClass();
        Class cls2=String.class;
        Class cls3=Class.forName("java.lang.String");
        System.out.println(cls1==cls2);
        System.out.println(cls1==cls3);
    }
}


  我们生成的对象都会有个字段记录该对象所属类在CLass类的对象的所在位置。如下图所示:

java.lang.Class类详解

  我们知道java中有多个加载器,每个加载器能载入多个类,所以只要取得Class类对象,就可利用其getClassLoader()方法取得该类加载器的引用。jvm为每种类管理着独一的Class对象。因此我们可以用双等号操作符来比较对象:a1.getClass()==A.class;应该返回的是true。 

 

java.lang.Class类详解

2.反射机制


》》定义

  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。


》》与Class类关系

  Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。也就是说,ClassLoader找到了需要调用的类时(java为了调控内存的调用消耗,类的加载都在需要时再进行,很抠但是很有效),就会加载它,然后根据.class文件内记载的类信息来产生一个与该类相联系的独一无二的Class对象。该Class对象记载了该类的字段,方法等等信息。以后jvm要产生该类的实例,就是根据内存中存在的该Class类所记载的信息(Class对象应该和我所了解的其他类一样会在堆内存内产生、消亡)来进行。而java中的Class类对象是可以人工自然性的(也就是说开放的)得到的(虽然你无法像其他类一样运用构造器来得到它的实例,因为Class对象都是jvm产生的。不过话说回来,客户产生的话也是无意义的),而且,更伟大的是,基于这个基础,java实现了反射机制。


》》反射机制功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法

》》反射机制API

  在JDK中,主要由以下类来实现Java反射机制,这些类(除了第一个)都位于java.lang.reflect包中:

  • Class类:代表一个类,位于java.lang包下
  • Field类:代表类的成员变量(成员变量也称为类的属性)
  • Method类:代表类的方法
  • Constructor类:代表类的构造方法
  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法

3.Class类使用


》》获取Class对象

  • 通过Object类的getClass()方法实现:Class c1 = 对象.getClass();
  • 通过Class类的静态方法forName()实现:Class c2 = Class.forName(“MyObject”);
  • T是一个已定义类型,T.class(.class文件名)就代表Class对象,例如:Class c3 = Manager.class;
    Class c4 = int.class;  
    Class c5 = Double[].class;

  这里需要解释一下:请记住一句话,java中,一切皆对象。也就是说,基本类型int float 等也会在jvm的内存池像其他类型一样中生成一个Class对象。而数组等组合型数据类型也是会生成一个Class对象的,而且更令人惊讶的是,java中数组的本来面目其实就是某个类,惊讶中的惊讶是,含有相同元素的相同维数的数组还会共同享用同一个Class对象!其实根据我的臆想,数组的length性质应该就保存在这个Class对象里面。


》》常用方法

  • getName(),一个Class对象描述了一个特定类的特定属性,而这个方法就是返回String形式的该类的简要描述。
  • newInstance(),可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的默认构造方法。例如:
    MyObject x = new MyObject();
    MyObject y = x.getClass().newInstance();
  • getClassLoader(),返回该Class对象对应的类的类加载器。
  • getSuperClass(),返回某子类所对应的直接父类所对应的Class对象
  • isArray(),判定此Class对象所对应的是否是一个数组对象


》》基本方法

getClassLoader() 
获取该类的类装载器。 
getComponentType() 
如果当前类表示一个数组,则返回表示该数组组件的 Class 对象,否则返回 null。 
getConstructor(Class[]) 
返回当前 Class 对象表示的类的指定的公有构造子对象。 
getConstructors() 
返回当前 Class 对象表示的类的所有公有构造子对象数组。 
getDeclaredConstructor(Class[]) 
返回当前 Class 对象表示的类的指定已说明的一个构造子对象。 
getDeclaredConstructors() 
返回当前 Class 对象表示的类的所有已说明的构造子对象数组。 
getDeclaredField(String) 
返回当前 Class 对象表示的类或接口的指定已说明的一个域对象。 
getDeclaredFields() 
返回当前 Class 对象表示的类或接口的所有已说明的域对象数组。 
getDeclaredMethod(String, Class[]) 
返回当前 Class 对象表示的类或接口的指定已说明的一个方法对象。 
getDeclaredMethods() 
返回 Class 对象表示的类或接口的所有已说明的方法数组。 
getField(String) 
返回当前 Class 对象表示的类或接口的指定的公有成员域对象。 
getFields() 
返回当前 Class 对象表示的类或接口的所有可访问的公有域对象数组。 
getInterfaces() 
返回当前对象表示的类或接口实现的接口。 
getMethod(String, Class[]) 
返回当前 Class 对象表示的类或接口的指定的公有成员方法对象。 
getMethods() 
返回当前 Class 对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。 
getModifiers() 
返回该类或接口的 Java 语言修改器代码。 
getName() 
返回 Class 对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。 
getResource(String) 
按指定名查找资源。 
getResourceAsStream(String) 
用给定名查找资源。 
getSigners() 
获取类标记。 
getSuperclass() 
如果此对象表示除 Object 外的任一类, 那么返回此对象的父类对象。 
isArray() 
如果 Class 对象表示一个数组则返回 true, 否则返回 false。 
isAssignableFrom(Class) 
判定 Class 对象表示的类或接口是否同参数指定的 Class 表示的类或接口相同,或是其父类。 
isInstance(Object) 
此方法是 Java 语言 instanceof 操作的动态等价方法。 
isInterface() 
判定指定的 Class 对象是否表示一个接口类型。 
isPrimitive() 
判定指定的 Class 对象是否表示一个 Java 的基类型。 
newInstance() 
创建类的新实例。 
toString() 
将对象转换为字符串。


http://www.cnblogs.com/octobershiner/archive/2012/03/18/2404751.html

http://www.cnblogs.com/mengdd/archive/2013/01/26/2877972.html

http://azrael6619.iteye.com/blog/429797

http://lavasoft.blog.51cto.com/62575/15433/

http://blog.csdn.net/nieweilin/article/details/5908165

http://www.cnblogs.com/whgw/archive/2011/10/04/2198837.html

http://blog.csdn.net/bingduanlbd/article/details/8424243/

http://utopialxw.iteye.com/blog/1220476

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/139738.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • excel批量导入图片 宏_怎么启用excel的宏

    excel批量导入图片 宏_怎么启用excel的宏准备图片格式规范:C盘的picture文件夹,放100张有序命名的图片,即1.jpg,2.jpg,3.jpg…100.jpg插入图片规则:按照图片的顺序,依次插入表格的A列,让每个图片一个单元

    2022年8月6日
    13
  • pycharm运行后出现process finished_pycharm进程已结束,退出代码0

    pycharm运行后出现process finished_pycharm进程已结束,退出代码0pycharm运行代码只显示Processfinishedwithexitcode0的解决办法通过右键xxx.py点击run按钮执行文件,提示Processfinishedwithexitcode0但是通过py.test的命令就可以执行成功且无以下的绿色执行按钮只需要在以下路径中进行设置然后重启pycharm就可以:…

    2022年8月29日
    1
  • 40个容易上瘾的HTML5网页游戏,总有一款适合你[通俗易懂]

    40个容易上瘾的HTML5网页游戏,总有一款适合你[通俗易懂]我记得姐姐家的孩子在刚刚才学会走路,说话还不能完整的时候就已经能自己用小手点出小游戏的网站来一个人自娱自乐。我一直在想这一代跟着计算机一起茁壮成长的孩子会不会也和美国那一代人一样,出现9岁的黑客和计算机天才。但是并不是信息的成长就能让教育同步。很多时候我们会发现教育在发展的大环境中并没有什么创新的思考。不管怎么说,我们还是需要小盆友们能有足够的想象力。不要被束缚!今天分享的是40个HTML5的网页

    2022年5月24日
    29
  • Java判断闰年

    Java判断闰年importjava.util.Scanner;/**判断某一年是否为闰年*通过Scanner输入一个年份,然后判断该年是否是闰年*闰年判断标准(满足任何一个)*1.如果能够被4整除,但是不能被100整除*2.能够被400整除*/publicclassHelloWorld{ publicstaticvoidmain(String[]args){ while(true) { System.out.println(“请输入年份:”); Scanner

    2022年7月9日
    12
  • win7电脑卡顿严重解决方法_电脑卡顿一下

    win7电脑卡顿严重解决方法_电脑卡顿一下最近有很多游戏玩家和小编说win7电脑玩2D游戏经常发生卡顿,游戏卡顿问题确实让玩家苦恼,因为导致2D游戏经常发生卡顿的原因有很多种,那么win7电脑玩2D游戏经常发生卡顿怎么办?不要着急,针对此问题,下面小编告诉大家造成2D游戏经常发生卡顿的六大解决方法。解决方法一:1、建议下载并安装【百度电脑专家】,2、打开【百度电脑专家】,在搜索框内输入“玩游戏卡”,在搜索结果里面选择第一项的【立即修复】,…

    2022年9月11日
    0
  • 初次尝试使用VisualSFM记录

    初次尝试使用VisualSFM记录  对于SFM一直觉得高大上又神秘,一年前粗略的了解过一下,今年有时间尝试深入了解SFM,对于初学者来说,VisualSFM真的时非常好的感受SFM的免费软件,于是通过其他博客的指导(没去看官方的英文版,容易犯困),做了一个3D模型出来,感觉还挺好玩,记录一下。  实际上,VisualSFM只做了一部分工作,优化是用MeshLab做的,所以分两个环节:   1.VisualSF…

    2022年6月20日
    22

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号