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. [FAQ] 夏玉米 按规则查询域名靠谱吗 ?

    很早就有一个网站叫 夏玉米,可以按规则查询和注册域名,那么它真如我们想的那样 可以找到好域名吗? 虽然看起来很好用,实际上夏玉米的查询只是针对它自己的数据库,不包含未在其平台注册的域名,所以大家要失望 ...

  2. SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息

    SpringBoot实现WebSocket发送接收消息 + Vue实现SocketJs接收发送消息 参考: 1.https://www.mchweb.net/index.php/dev/887.htm ...

  3. 简说Python之循环语句

    目录 Python的运算逻辑 Python条件语句 Python循环语句 Python while循环 Python for 循环 条件语句和循环语句是程序常用的一种基础语法,从语言上来说,能说清楚的 ...

  4. Swift File Manager 三种文件路径查找方法对比

    目录 1. 引言 2. 三种文件路径查找方法 2. 1 NSSearchPathForDirectoriesInDomains(_:_:_:) 2.2 urls(for:in:) 2.3 url(fo ...

  5. docker-compose搭建的Mysql主主复制

    注意下面几点: 1)要保证同步服务期间之间的网络联通.即能相互`ping`通,能使用对方授权信息连接到对方数据库(防火墙开放3306端口). 2)关闭selinux. 3)同步前,双方数据库中需要同步 ...

  6. 30分钟带你搞定Dokcer部署Kafka集群

    docker网络规划 docker network create kafka-net --subnet 172.20.0.0/16 docker network ls zookeeper1(172.2 ...

  7. php的下载与安装

    一,进入到php的官方网站   https://www.php.net/   ,进入到下载页面: 选择 PHP 7.2.30 的Windows版本 具体的下载页面版本区分: 下载后,得到如下压缩包到如 ...

  8. Android 11(R) MultiMedia(十五)MediaCodec同步模式实现一个简易播放器

    这一节是实践,学习android原生SimplePlayer并自己码一遍,果然学到很多. MyPlayer.h #include <media/stagefright/foundation/AH ...

  9. 来自多彩世界的控制台——C#控制台输出彩色字符画

    引言 看到酷安上有这样一个活动,萌生了用 C# 生成字符画的想法,先放出原图.   酷安手绘牛啤     §1 黑白 将图像转换成字符画在 C# 中很简单,思路大致如下: 加载图像,逐像素提取明度. ...

  10. AIAGC导航(aiagc.com): 最全的AI工具导航网站

    AIAGC导航是一个专注于AI人工智能工具网站推荐的导航网站,可以帮助大家发现最新.最好用.最有趣的AI绘画.AI智能写作助手.AI聊天机器人.AI配音.AI音乐.AI换脸等各种AI工具应用软件,让A ...