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构造。
    相关文章
    |
    5月前
    |
    安全 前端开发 Java
    JDK源码级别彻底剖析JVM类加载机制
    JDK源码级别彻底剖析JVM类加载机制
    |
    5月前
    |
    缓存 Dubbo Java
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    趁同事上厕所的时间,看完了 Dubbo SPI 的源码,瞬间觉得 JDK SPI 不香了
    |
    2月前
    |
    Android开发
    AS错误:Duplicate class kotlin.xxx.jdk8.DurationConversionsJDK8Kt found in modules kotlin-stdlib-1.8.22
    本文描述了Android Studio中遇到的"Duplicate class found in modules"错误的解决方法,通过在`app/build.gradle`文件中使用`constraints`来排除过时的kotlin-stdlib-jdk7和kotlin-stdlib-jdk8依赖,解决了依赖冲突问题。
    83 1
    |
    2月前
    |
    Java API 开发者
    Jdk动态代理为啥不能代理Class?
    该文章主要介绍了JDK动态代理的原理以及为何JDK动态代理不能代理Class。
    Jdk动态代理为啥不能代理Class?
    |
    2月前
    |
    算法 安全 Java
    深入JDK源码:揭开ConcurrentHashMap底层结构的神秘面纱
    【8月更文挑战第24天】`ConcurrentHashMap`是Java并发编程中不可或缺的线程安全哈希表实现。它通过精巧的锁机制和无锁算法显著提升了并发性能。本文首先介绍了早期版本中使用的“段”结构,每个段是一个带有独立锁的小型哈希表,能够减少线程间竞争并支持动态扩容以应对高并发场景。随后探讨了JDK 8的重大改进:取消段的概念,采用更细粒度的锁控制,并引入`Node`等内部类以及CAS操作,有效解决了哈希冲突并实现了高性能的并发访问。这些设计使得`ConcurrentHashMap`成为构建高效多线程应用的强大工具。
    44 2
    |
    2月前
    |
    Oracle Java 关系型数据库
    简单记录在Linux上安装JDK环境的步骤,以及解决运行Java程序时出现Error Could not find or load main class XXX问题
    本文记录了在Linux系统上安装JDK环境的步骤,并提供了解决运行Java程序时出现的"Error Could not find or load main class XXX"问题的方案,主要是通过重新配置和刷新JDK环境变量来解决。
    77 0
    |
    4月前
    |
    Java
    JDK version和class file version对应关系
    JDK version和class file version对应关系
    |
    4月前
    |
    Java Spring
    深入解析Spring源码,揭示JDK动态代理的工作原理。
    深入解析Spring源码,揭示JDK动态代理的工作原理。
    50 0
    |
    5月前
    |
    Java
    916.【Java】javap 查看 class 文件的jdk编译版本
    916.【Java】javap 查看 class 文件的jdk编译版本
    145 2
    |
    5月前
    |
    设计模式 Java
    根据JDK源码Calendar来看工厂模式和建造者模式
    根据JDK源码Calendar来看工厂模式和建造者模式