java有个Class的基类,高级编程的时候,务必要理解这个。

粗略看下,可以明白了解Class这个类对于了解和掌握java非常重要。

Class这个类的包路径是:java.lang.Class<T>

可以看出来这是一个非常基础,非常核心的类,因为它的包路径位于java.lang,即java的语言包下面,可谓核心的核心。

 一、开个好头

a.先看引入部分

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.AnnotatedType;
import java.lang.ref.SoftReference;
import java.io.InputStream;
import java.io.ObjectStreamField;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.Objects;
import sun.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.repository.ClassRepository;
import sun.reflect.generics.repository.MethodRepository;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import sun.reflect.annotation.*;
import sun.reflect.misc.ReflectUtil;

为了简化,我们把sun.refect.annotation.*算作一个,共有import语句45个,其中:27个和reflect(反射)有关,10个和java.util明显有关,3个和security(安全)有关,2个和io有关,余者3个。

所以这个Class类,可以大体理解为和反射,工具,安全,io有关的工具类。依赖那么多反射是因为必须通过反射来解析目标类或者对象。

如果可以,也大体可以这么认为:Class类大体就是通过反射功能分析和处理类的工具类。虽然它不仅仅是这样。

b.看下这个类的头部注释

头部的注释可谓是本类意图的较好表达。

为了便于大家查看,这里只列出JavaDoc显示的结果:

java.lang.Class<T>

Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind ofclass and an annotation is a kind of interface. 
Every array also belongs to a class that is reflected as a Class objectthat is shared by all arrays with the same element type and number of dimensions.
The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor. Instead Classobjects are constructed automatically by the Java Virtual Machine as classesare loaded and by calls to the defineClass method in the classloader. The following example uses a Class object to print theclass name of an object: void printClassName(Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}
It is also possible to get the Class object for a namedtype (or for void) using a class literal. See Section 15.8.2 of The Java Language Specification.For example:
System.out.println("The name of class Foo is: "+Foo.class.getName());

Type Parameters:<T> the type of the class modeled by this Classobject. For example, the type of String.class is Class<String>.
Use Class<?> if the class being modeled isunknown.
Since:JDK1.0
Author:unascribed
See Also:java.lang.ClassLoader.defineClass(byte [], int, int)

当然,也不仅仅是这个注释重要,整个类文件有3639行(rt.jar中,版本1.8.0_301),还有许多的属性和方法都具有较长的注释。

后面的注释后面说,开头这里先说说这一段话什么意思:

原文:
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface.
Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions.
The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the classloader.

译文:
类Class的实例描绘了正在jvm中运行的类的接口。一个enum(枚举)是一种类,一个annotation(注解)是一种接口。
每个array也归属于一个类,这个类表示一个Class对象,这个对象被具有同个元素类型和维度的所有数组共享。
原始的java类型(boolean,byte,char,short,int,long,float和double),以及关键字void也被表示为一个Class对象。
Class没有公共的构造函数。但是Class对象可以被jvm自动构造,具体的方式是当类被加载,并由classloader执行defineClass方法。

c.历史

看一个图片:

注:

a.以上统计仅仅基于@since关键字,但还有许多方法是没有@since的,这些就是1.0就提供的。since1.0是放在Class定义头之上。

b.原来since后面跟的不都是 数字,例如1.0,1.8,而是有的 以JDK开头,有的直接就是一个数字。 从1.2(包含1.2)之后就不再带有JDK字眼,而是形如 @since 1.5

有意思吧,这个统计充分表明了几个信息:

1.从1.0开始java就构思这个基类,这个@since JDK1.0是放在类头,原文“ * @since   JDK1.0”

2.版本 1.1,1.5,1.8引入了最多的,大体占据了89%

针对每个版本引入的新特性,对照每个发行申明中的新特性,就可以发现二者之间的紧密关系,而这种关联是想当然的。

二、定义

a. 定义

public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement

关键点:泛型、可序列化、通用定义、类型、注解

说明Class可以处理各种类的定义,类型和注解。

b.罕见关键字列表

这个罕见,是说在一般的应用编程中。

先理解这个词语,方能继续分析。

  • ConstantPool

    • 含义:常量池,是太阳公司反射包中一个类,用于获取jvm常量有关信息

三、构成

内容太多,没有必要一一罗列,只列出自己关注的部分。

函数和方法

  • forName
  • newInstance
  • getGenericSuperclass
  • getDeclaredFields
  • getDeclaredMethods
  • getResource
  • getAnnotations
  • getAnnotatedInterfaces

四、主要功能

  • 获取类或者接口信息
  • 反射,一遍动态编程

五、Object和getClass

为了配合反射,java的祖类Object,增加了一些重要的内容:

public final native Class<?> getClass();

这是一个泛型的native方法,且是final,即由jvm native块执行。

该方法的注释:

* @return The {@code Class} object that represents the runtime
      *         class of this object.

有了这个方法,反射就变得很容易了。

除了通过getClass获取Class,也可以直接在类名后跟上class获取,例如:

Class<ChineseMan> cc= ChineseMan.class;

      直接看Object本身的定义并没有这个属性,但确可以使用,这是因为编译器自动做了这个活。

六、JVM

Class类的大量功能和内容和JVM是绑定在一起的。 贴几个JVM结构图:(注下图直接bing获取的,没有注意来源)

再来一个更加清楚的:

关于jvm,非长篇大论不足以详知,非本文内容,有关内容自行搜索,或者查看以下内容:

本文列出jvm内容,是为了说明native这个东西。native是jvm活着的主要目的,当然jvm不仅仅是native还有Excecution Engine(执行引擎)。因为这个,java其实够慢的。

七、示例

package study.base.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.lang.StringUtils; import study.base.classes.ChineseMan; public class ReflectTest { public static void printClassTree(Class<?> c) {
List<String> classNameList=new ArrayList<String>();
getClassTree(c,classNameList); int lvl=classNameList.size();
for(int i=lvl-1;i>=0;i--) {
int paddingQty=lvl-i;
String paddingString=StringUtils.leftPad("", paddingQty,"-");
System.out.println(paddingString+classNameList.get(i));
} } public static void getClassTree(Class<?> c,List<String> result){
result.add(c.getName());
if (c.getSuperclass()!=null) {
getClassTree(c.getSuperclass(),result);
}
} public static void printMethod(Method[] methods) {
if (methods.length==0) {
System.out.println("没有任何方法!");
}
for (Method item:methods) {
System.out.println(item.getDeclaringClass().getName()+":"+item.getName());
Parameter[] params=item.getParameters();
if (params.length>0) {
for(Parameter p:params) {
System.out.println(
" "+p.getParameterizedType().getTypeName()+" "+p.getName()
);
}
}
}
} public static void printFileds(Field[] fields) {
for(Field item:fields) {
System.out.println(item.getName()+":"+item.getType().isPrimitive());
}
} @SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
ChineseMan cm=new ChineseMan("lzf");
cm.setLeftPadding(" --");
Class<ChineseMan> cc=ChineseMan.class;
printClassTree(cc);
System.out.println("-------------------------------------------------------");
System.out.println("获取类ChineseMan特有方法");
Method[] methods=cc.getDeclaredMethods();
printMethod(methods); System.out.println("-------------------------------------------------------");
System.out.println("获取类ChineseMan的所有属性");
printFileds(cc.getDeclaredFields()); System.out.println("-------------------------------------------------------");
System.out.println("执行cm的当前类方法--具有返回结果");
Class voidClass=Void.class;
String voidClassName=voidClass.getSimpleName().toLowerCase();
for (Method item:methods) {
Class returnType=item.getReturnType();
String returnTypeClassName=returnType.getSimpleName().toLowerCase();
if (!returnTypeClassName.equals(voidClassName)) {
try {
Object result=item.invoke(cm);
System.out.println(item.getName()+":"+result.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
} System.out.println("-------------------------------------------------------");
System.out.println("获取ChineseMan所有方法(含祖先)");
methods=cc.getMethods();
printMethod(methods); System.out.println("-------------------------------------------------------");
System.out.println("执行ChineseMan的父亲类"+cc.getSuperclass().getName()+"方法");
System.out.println("-------------------------------------------------------");
methods=cc.getSuperclass().getDeclaredMethods();
for (Method item:methods) {
//System.out.println(item.getName());
if (item.getParameters().length==0) {
try {
System.out.print(" "+item.getName()+":");
if (!item.getReturnType().getSimpleName().toLowerCase().equals(voidClassName)) {
Object result=item.invoke(cm);
System.out.println(result.toString());
}
else {
item.invoke(cm);
} } catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
else {
System.out.println(" "+item.getName()+"(...)");
} }
} }

直接结果如下:

-java.lang.Object
--study.base.classes.Organisms
---study.base.classes.Animal
----study.base.classes.Human
-----study.base.classes.Man
------study.base.classes.ChineseMan
-------------------------------------------------------
获取类ChineseMan特有方法
study.base.classes.ChineseMan:set斗志
java.lang.String 斗志
study.base.classes.ChineseMan:get斗志
study.base.classes.ChineseMan:set力量
java.lang.String 力量
study.base.classes.ChineseMan:get力量
study.base.classes.ChineseMan:setSoldier
boolean isSoldier
study.base.classes.ChineseMan:isSoldier
study.base.classes.ChineseMan:toString
-------------------------------------------------------
获取类ChineseMan的所有属性
isSoldier:true
斗志:false
力量:false
-------------------------------------------------------
执行cm的当前类方法--具有返回结果
get斗志:100
get力量:100
isSoldier:true
toString:ChineseMan{
姓名:lzf,
力量:100,
斗志:100
}
-------------------------------------------------------
获取ChineseMan所有方法(含祖先)
study.base.classes.ChineseMan:set斗志
java.lang.String 斗志
study.base.classes.ChineseMan:get斗志
study.base.classes.ChineseMan:set力量
java.lang.String 力量
study.base.classes.ChineseMan:get力量
study.base.classes.ChineseMan:setSoldier
boolean isSoldier
study.base.classes.ChineseMan:isSoldier
study.base.classes.ChineseMan:toString
study.base.classes.Man:born
study.base.classes.Man:work
study.base.classes.Man:eat
study.base.classes.Man:getLeftPadding
study.base.classes.Man:familywork
study.base.classes.Man:growOld
study.base.classes.Man:disappear
study.base.classes.Man:fallSick
study.base.classes.Man:fight
study.base.classes.Man:die
study.base.classes.Man:bear
study.base.classes.Man:teach
study.base.classes.Man:setLeftPadding
java.lang.String leftPadding
study.base.classes.Man:run
study.base.classes.Human:setGender
java.lang.String gender
study.base.classes.Human:getGender
study.base.classes.Human:sleep
study.base.classes.Animal:getEatable
study.base.classes.Animal:setEatable
java.lang.Boolean eatable
study.base.classes.Organisms:setLocation
java.lang.String location
study.base.classes.Organisms:setType
java.lang.String type
study.base.classes.Organisms:getName
study.base.classes.Organisms:getLocation
study.base.classes.Organisms:setName
java.lang.String name
study.base.classes.Organisms:getType
java.lang.Object:wait
java.lang.Object:wait
long arg0
int arg1
java.lang.Object:wait
long arg0
java.lang.Object:equals
java.lang.Object arg0
java.lang.Object:hashCode
java.lang.Object:getClass
java.lang.Object:notify
java.lang.Object:notifyAll
-------------------------------------------------------
执行ChineseMan的父亲类study.base.classes.Man方法
-------------------------------------------------------
born: --生当作人杰,死亦为鬼雄!
work: --锄禾日当午,汗滴禾下土!
以天为盖,以地为舆
eat: --但使残年饱吃饭,只愿无事常相见
getLeftPadding: --
familywork: --子不教,父之过!
growOld: --儿童相见不相识,笑问客从何处来!
disappear: --神龟虽寿,犹有竞时;腾蛇乘雾,终成土灰
fallSick: --僵卧孤村不自哀,尚思为国戍轮台
fight: --黄沙百战穿金甲,不破楼兰终不还
die: --人生自古谁无死,留取丹心照汗青
bear: --男人不能生孩子
teach: --师者,所以传道授业解惑者也!
setLeftPadding(...)
run: --醉里挑灯看剑,梦回吹角连营!

八、参考资料

参考内容太多,不一一列出,有的已经在前文列出。

Java发行历史(截止1.8) https://blog.csdn.net/wq6ylg08/article/details/91351603

关于java-Class类的简单分析的更多相关文章

  1. rocketmq中的NettyRemotingClient类的简单分析

    rocketmq中的NettyRemotingClient类的简单分析 Bootstrap handler = this.bootstrap.group(this.eventLoopGroupWork ...

  2. java基础---->hashSet的简单分析(一)

    对于HashSet而言,它是基于HashMap实现的,底层采用HashMap来保存元素的.今天我们就简单的分析一下它的实现.人生,总会有不期而遇的温暖,和生生不息的希望. HashSet的简单分析 一 ...

  3. Java简单实验--关于课后提到的java重载函数的简单分析

    根据这一小段代码,获得了以下的测试截图: 简单分析:根据输出结果,判断这段代码用到了两个不同的函数方法,输出的不止有double类型的数,还有整型的数. 又根据类中的定义情况,square是根据判断传 ...

  4. Java File类的简单使用

    Java File的简单使用(创建.删除.遍历.判断是否存在等) Java文件类以抽象的方式代表文件名和目录路径名.该类本身不能用来读数据或写数据,它主要用于磁盘上文件和目录的创建.文件的查找和文件的 ...

  5. Java自定义异常类的简单实现

    学习目标: 掌握自定义异常类 例题: 需求:自定义异常类,简单判断是否注册成功 代码如下: RegisterException类: /** * @author YanYang * @projectNa ...

  6. Java程序内存的简单分析

    这篇文章将简单的说明下当我们运行Java程序时JVM(Java虚拟机)的内存分配情况. 首先我们先来感观的认识下几个名词: 1.栈,一般来说,基本数据类型直接在栈中分配空间,局部变量(在方法代码段中定 ...

  7. Java Properties类源码分析

    一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...

  8. Java内存模型JMM简单分析

    参考博文:http://blog.csdn.net/suifeng3051/article/details/52611310 http://www.cnblogs.com/nexiyi/p/java_ ...

  9. java.lang.IllegalStateException异常简单分析和简单解决

    我们在做文件上传或者下载,或者过滤等操作时,可能要用到页面的输出流. 例如在JSP使用: response.reset(); response.setContentType(”application/ ...

  10. Tomcat容器运行struts2+spring+mybatis架构的java web应用程序简单分析

    1.具体的环境为 MyEclipse 8.5以及自带的tomcat spring3.0.5 struts2.3.15.1 mybatis3.0.5 2.想弄明白的一些问题 tomcat集成spring ...

随机推荐

  1. 19、python 脚本

    1.python 安装及配置 下载地址 python2 和 python3 共存安装 2.python 可视化 import turtle turtle.pensize(2) #画一个小圆 turtl ...

  2. Docker推送镜像到Dockerhub

    登录docker hub官网注册账号 https://hub.docker.com/signup 登录账户,创建一个仓库 "Create Repository"--> 输入命 ...

  3. get pull报错 Please commit your changes or stash them before you merge

    当本地分支和远程修改了同一个文件代码,pull远程分支的代码的时候会出现文件冲突 出现这个错误 Please commit your changes or stash them before you ...

  4. 4G EPS 第四代移动通信系统

    目录 文章目录 目录 4G EPS 4G EPS 4G(the 4th generation mobile communication technology,第四代移动通信技术)提供了 3G 不能满足 ...

  5. Springboot 项目集成 PageOffice V6 最简单代码

    本文描述了PageOffice产品在Springboot项目中如何集成调用.(本示例使用了Thymeleaf模板引擎) 新建Springboot项目:pageoffice6-springboot2-s ...

  6. 节能降耗 | AIRIOT智慧电力综合管理解决方案

      电力技术的发展推动各行各业的生产力,与此同时,企业中高能耗设备的应用以及输配电过程中的电能损耗,也在一定程度上加剧了电能供应压力.以工业制造业为例,企业的管理水平.能耗结构.生产组织方式都关系到能 ...

  7. RuoYi(若依)前后端分离版本,windows下部署(nginx)

    摘自:https://blog.csdn.net/yueyekkx/article/details/105505490 上一篇用了tomcat部署(https://blog.csdn.net/yuey ...

  8. 【C#】关于ACCESS数据库insert into报错:标准表达式中数据类型不匹配

    如果插入列有日期/时间类型,使用C#时,var ptime = new OleDbParameter("@DtTime", OleDbType.Date); OleDbType.D ...

  9. layui-框架学习小总结

    主要6点: 1.导航栏变成了类似tab的页签,支持关闭,点击刷新. 2.左侧菜单树可隐藏. 3.树的搜索. 4.表格的新增行,并保存到后台. 5.表格 加载 下拉框,并赋值,选择了值后把值同步到表格对 ...

  10. Linux中根据关键字获取某一行的行号

    [root@localhost ~]# cat test.txt 123213 ehualu.server ehualu.docker 10.0.0.10 ehualu.server ehualu.d ...