JDK源码(15)-Class

简介: JDK源码(15)-Class

一、概述

Class的实例代表着正在运行的Java应用程序的类和接口。枚举是一种类,而直接是一种接口。每一个数组也属于一个类,这个类b被反射为具有相同元素类型和维数的所有数组共享的类对象。八大基本树类型和void关键字也都有属于自己的类对象。

Class没有public的构造器,由JVM虚拟机调用类加载器中的defineClass方法来构造。

二、代码剖析

类定义:

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

image.gif

构造方法:这是一个有参的私有构造,只能有2JVM虚拟机在创建对象时使用,这个构造可以防止默认的无参构造被使用。

private Class(ClassLoader loader) {
       classLoader = loader;
    }

image.gif

toString方法:会打印一个Class是类还是接口,以及它的名字。

public String toString() {
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
            + getName();
    }

image.gif

toGenericString():jdk1.8新增方法,返回包含修饰符和参数在内的类信息。

public String toGenericString() {
        if (isPrimitive()) {
            return toString();
        } else {
            StringBuilder sb = new StringBuilder();
            // Class modifiers are a superset of interface modifiers
            int modifiers = getModifiers() & Modifier.classModifiers();
            if (modifiers != 0) {
                sb.append(Modifier.toString(modifiers));
                sb.append(' ');
            }
            if (isAnnotation()) {
                sb.append('@');
            }
            if (isInterface()) { // Note: all annotation types are interfaces
                sb.append("interface");
            } else {
                if (isEnum())
                    sb.append("enum");
                else
                    sb.append("class");
            }
            sb.append(' ');
            sb.append(getName());
            TypeVariable<?>[] typeparms = getTypeParameters();
            if (typeparms.length > 0) {
                boolean first = true;
                sb.append('<');
                for(TypeVariable<?> typeparm: typeparms) {
                    if (!first)
                        sb.append(',');
                    sb.append(typeparm.getTypeName());
                    first = false;
                }
                sb.append('>');
            }
            return sb.toString();
        }
    }

image.gif

public static Class<?> forName(String className)

通过类或接口的名字获取对应的Class对象。

forName(className,true, this.getClass().getClassLoader()):

Class.forName(className)实际上是调用Class.forName(className,true, this.getClass().getClassLoader())。第二个参数,是指Class被loading后是不是必须被初始化。最终都调用了native方法去实现。

public T newInstance() throws InstantiationException, IllegalAccessException

为类创建一个类实例,这个方法用的比较多。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。

public native boolean isArray():判断对象是否为数组,由native实现。

public native boolean isPrimitive():判断是否基本数据类型。

isSynthetic():当且仅当这个类是Java语言规范定义的一种合成类此方法返回true。synthetic总的来说,是由编译器引入的字段、方法、类或其他结构,主要用于JVM内部使用。有关合成类请参考:synthetic Java合成类型_a327369238的博客-CSDN博客

public ClassLoader getClassLoader():返回类加载器。

接着有一大堆的get方法,可以获取类型参数,父类,泛型父类,包,接口们,泛型接口们,方法,属性等各种各样可用于反射的方法。

三、总结

最后用最简单的描述来区分new关键字和newInstance()方法的区别:

    1. newInstance: 弱类型。低效率。只能调用无参构造。  
    2. new: 强类型。相对高效。能调用任何public构造。
    相关文章
    |
    4天前
    |
    安全 前端开发 Java
    JDK源码级别彻底剖析JVM类加载机制
    JDK源码级别彻底剖析JVM类加载机制
    |
    4天前
    |
    缓存 Dubbo Java
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    |
    4天前
    |
    缓存 Java Spring
    Spring 源码阅读 66:基于 JDK 的 AOP 代理如何获取拦截器链(4)- 将 Advice 封装为拦截器
    【1月更文挑战第1天】本文分析了 Advice 被封装成 MethodInterceptor 的过程,Spring AOP 用到的五种 Advice 中,有些本身就是 MethodInterceptor 的实现类,而有些需要通过适配器的封装。
    44 0
    |
    8月前
    |
    设计模式 Java 程序员
    太爆了!阿里最新出品2023版JDK源码学习指南,Github三天已万赞
    最近后台收到很多粉丝私信,说的是程序员究竟要不要去读源码?当下行情,面试什么样的薪资/岗位才会被问到源码? 对此,我的回答是:一定要去读,并且要提到日程上来! 据不完全统计,现在市面上不管是初级,中级,还是高级岗,面试的时候都有可能会问到源码中的问题,它已经成为程序员常规必备的一个技术点。如果你当下想通过一个面试,或者想把中级薪资要到相对于比较高的话,源码这块就必须要会。
    100 0
    |
    4天前
    |
    Java
    916.【Java】javap 查看 class 文件的jdk编译版本
    916.【Java】javap 查看 class 文件的jdk编译版本
    97 2
    |
    4天前
    |
    算法 Java 索引
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    【数据结构与算法】4、双向链表(学习 jdk 的 LinkedList 部分源码)
    35 0
    |
    4天前
    |
    设计模式 Java
    根据JDK源码Calendar来看工厂模式和建造者模式
    根据JDK源码Calendar来看工厂模式和建造者模式
    |
    4天前
    |
    Java Linux iOS开发
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    Spring5源码(27)-静态代理模式和JDK、CGLIB动态代理
    24 0
    |
    4天前
    |
    XML Java 数据格式
    Spring 源码阅读 70:基于 JDK 的 AOP 代理拦截器链执行(4)- 容易被忽略的 ExposeInvocationInterceptor
    【1月更文挑战第5天】本文分析了 Spring AOP 拦截器链中的一个特殊拦截器 ExposeInvocationInterceptor 的注册的时机以及它的作用。至此,基于 JDK 的 AOP 代理拦截器链执行的逻辑就分析完了。
    451 0
    |
    4天前
    |
    Java 索引 Spring
    Spring 源码阅读 69:基于 JDK 的 AOP 代理拦截器链执行(3)- MethodInterceptor 分析
    【1月更文挑战第4天】本文详细分析了 Spring AOP 中五种增强类型对应的拦截器中增强方法的执行逻辑,结合上一篇中分析的 ReflectiveMethodInvocation 中proceed方法的执行逻辑,就组成了完整的拦截器链递归调用的逻辑。
    35 0