Java Class的理解

253 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

理解或许片面不够成熟,但是我觉得理解只是在不违背创作者本意下的一种自我说服,能“骗”过自己就行,仅供参考。

先从类说起

Java是一门面向对象的高级编程语言,更加符合人的思维、习惯。对象是什么呢(你对象也是对象!😏)?就是指世界上人的认知范围内的实体,可以是小到分子原子,可以大到星球宇宙等等。那类是什么呢?类就是某些具备公共特征实体的一种抽象。说人话就是对实体进行分类,有共同特征、行为的可分为一类(当然这个分类不是绝对的,也没有什么标准)。

再说说Class

有了类这个概念,使用者就可以将将万千实体抽象成类,方便管理、使用。但是类的数量是很多的(光是jre的类就够我们喝好几壶的了),多就意味着复杂。为了在复杂的程序运行出错后,我们能快速的定位错误,解决错误,就需要一种能有条不紊,清清楚楚的记录好每一种类的信息的机制或者载体。Class就是干这个的!

来看看Java中的Class

image.png 这是API文档中对Class的介绍,可以看出定义和普通的类没有任何区别,只是类的名字叫Class。但也有点小特殊,final修饰,代表是一个最终类,由Java虚拟机构建对象。表示的是正在运行中的Java应用程序中的类与接口。

类都有类名,访问修饰符,成员属性,类成员属性,行为方法,构造器等。这一系列是每一个类都具有的,Class也有,只是属性的含义,方法的功能作用相对于我们自定义的、官方提供的普通API类而言,有些特殊。方法暂不讨论,太多,拿属性来说,其中有一个内部类属性中的内容如下:

// reflection data that might get invalidated when JVM TI RedefineClasses() is called
private static class ReflectionData<T> {
    volatile Field[] declaredFields;
    volatile Field[] publicFields;
    volatile Method[] declaredMethods;
    volatile Method[] publicMethods;
    volatile Constructor<T>[] declaredConstructors;
    volatile Constructor<T>[] publicConstructors;
    // Intermediate results for getFields and getMethods
    volatile Field[] declaredPublicFields;
    volatile Method[] declaredPublicMethods;
    volatile Class<?>[] interfaces;

    // Value of classRedefinedCount when we created this ReflectionData instance
    final int redefinedCount;

    ReflectionData(int redefinedCount) {
        this.redefinedCount = redefinedCount;
    }
}

其中定义了Field、Method、Constructor、Class几个数组,有啥用呢?

Field就是类中所有属性所属的类。它描述类的一个字段信息,并提供动态的访问。

image.png 同理,Method就是描述方法的。

image.png Constructor就是描述构造器的。

image.png Class就是描述类(内部类)的。

类的属性,构造器,方法、内部类信息全部都会被装到对应的数组中去。

来张图表示一下

image.png 最终类的属性就被封装到File对象中,其余同理,这些对象又全部被放到Class的对象中,一个类就是一个Class对象

这也是为什么Java的反射技术能在运行时动态的获取类的信息,来创建类实例,运行类方法,使用属性等等操作了,因为啥都被记录得明明白白!

Class与类的关系,若要来个类比的话,我觉得就像是古代的史官一样,你哪个名人有啥性格,有啥不得了的鸟事,都给你记得明明白白清清楚楚的。

获取Class对象的方式

Java虚拟机加载了类,创建了类(Class)对象,那么我们想用的时候怎么获取呢?比如想要获取类的Class对象进行反射操作。有三种方式: code 1:

package demo;

public class ClassDemo {
    public static void main(String[] args) {
        /*方式1:通过类的全限定名来获取*/
        try {
            Class cl = Class.forName("demo.ClassDemo");
            System.out.println("cl.getName():"+cl.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /*方式2:通过对象获取*/
        ClassDemo classDemo = new ClassDemo();
        Class cl1 = classDemo.getClass();
        System.out.println("cl1.getSimpleName():"+cl1.getSimpleName());

        /*方式3:通过类名获取*/
        Class cl2 = ClassDemo.class;
        System.out.println("cl2.getTypeName():"+cl2.getTypeName());
    }
}

测试结果:

image.png 至于运用,以后再探究吧。。。