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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • python2 手动安装更新pip

    python2 手动安装更新pip

    2021年10月22日
  • Windows程序设计——窗口键盘消息滚动事件[通俗易懂]

    Windows程序设计——窗口键盘消息滚动事件[通俗易懂]设置头文件#include <Windows.h>#include “systems.h”以下是头文件内容#pragma once#include <Windows.h>#define NUMLINES ((int)(sizeof sysmetrics/sizeof sysmetrics[0]))struct { int Index; char sz…

  • SLAM技术分享_it技术分享社区

    SLAM技术分享_it技术分享社区同时定位与地图重建(SimultaneousLocalizationandMapping,SLAM),是机器人领域中的一项基础的底层技术,其希望机器人能在一个陌生的环境下实现自身的实时定位,同时能够重建出有关于环境的地图。随着近年无人驾驶、增强现实、虚拟现实等应用的兴起,作为实现这些应用的SLAM技术也越发引人注目。SLAM技术主要完成两项任务:自身定位与环境建图,也是让机器知道自己在哪里,已经周围的环境是啥。然而,如果想要精确的实现定位任务就不可避免的需要高精度的地图,而高精度的地图重建是需要以更

  • 整理计算机病毒的知识点,计算机病毒知识点整理「建议收藏」

    整理计算机病毒的知识点,计算机病毒知识点整理「建议收藏」《计算机病毒分析与防范技术》知识点整理本知识点涵盖期末考试的内容,请自行完善,以便用于开卷考试。7.※清除宏病毒的方法清除宏病毒方法一、验证是否感染了宏病毒?打开需要检查的文档,单击“文件”菜单栏,选择“另存为”命令,如果对话框中的保存类型固定为“文档模板”,则表示这个文件已经感染了宏病毒。二、清除宏病毒的方法1、OFFICE2003方法:打开文档,工具――宏――宏(或者使用组合键“Alt…

  • 怎么使用 eclipse 开发和运行 Java 程序呢?

    怎么使用 eclipse 开发和运行 Java 程序呢?·使用eclipse开发第一个程序我们在上一节建好的Java项目中,开始开发Java程序。首先,新建一个Java类。在src目录上右键单击,建立一个Java类。如图1所示。图1新建Java类入口出现新建类的开始界面,如图2所示。我们只需输入类名即可,其他不需做任何设置:图2指定Java类的名称点击Finish后,新建Java类成功,出现如图3所示。图3新建Java类完成在src下面出现了Welcome.java文件。点击该文件

  • pytest的assert_java单元测试断言

    pytest的assert_java单元测试断言前言断言是写自动化测试基本最重要的一步,一个用例没有断言,就失去了自动化测试的意义了。什么是断言呢?简单来讲就是实际结果和期望结果去对比,符合预期那就测试pass,不符合预期那就测试failed

发表回复

您的电子邮箱地址不会被公开。

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