为什么 Java 基元类型的修饰符是公共的、抽象的和最终的?

2022-09-02 01:55:42

在对Java类型进行一些反思的过程中,我遇到了一个我不明白的奇怪之处。

检查其修饰符返回 、 和 。我理解 和 ,但是在基元类型的存在对我来说是不明显的。为什么会这样?intpublicabstractfinalpublicfinalabstract

编辑:我不是在反思,而是在:Integerint

import java.lang.reflect.Modifier;

public class IntegerReflection {
    public static void main(final String[] args) {
        System.out.println(String.format("int.class == Integer.class -> %b", int.class == Integer.class));
        System.out.println(String.format("int.class modifiers: %s", Modifier.toString(int.class.getModifiers())));
        System.out.println(String.format("Integer.class modifiers: %s", Modifier.toString(Integer.class.getModifiers())));
    }
}

运行时的输出:

int.class == Integer.class -> false
int.class modifiers: public abstract final
Integer.class modifiers: public final

答案 1

根据 JLS 8.1.1.1 - 抽象类

抽象类是不完整的类,或被视为不完整的类。

根据定义,不能有 的实例。您无法编译此类代码:int.class

int a = new int();

没有 的构造函数。未创建任何对象。 甚至没有扩展。如果运行以下代码行,则结果为结果。intint.classObjectnull

System.out.println(int.class.getSuperclass());

因此,由于您永远不可能拥有 的真实实例,因此根据定义,它是 。此外,根据整数 API,字段(持有 )是一个仅表示基元类型的类。int.classabstractInteger.TYPEint.class

以下代码证明了这一点:

int a = 4;
System.out.println(int.class.isInstance(a));

这将返回 。false

因此,可能只是在系统中用于表示目的,如API中所述。事实上,还有一个类型但没有类型,这让我认为这主要与反射一起使用。不过,这只是猜想。int.classIntegervoid.classnull.class


如果有人感兴趣,本质上不包含反射包识别的任何内容,并且可能只是一个虚拟类。如果运行以下代码,您将看到它没有构造函数、没有字段和方法。int.class

Method[] intMethods = int.class.getMethods();

if(intMethods.length == 0) {
    System.out.println("No methods.");
}
else {
    for(Method method : intMethods) {
        System.out.println(method.getName());
    }
}

Constructor[] intConstructors = int.class.getConstructors();

if(intConstructors.length == 0) {
    System.out.println("No constructors.");
}
else {
    for(Constructor constructor: intConstructors) {
        System.out.println(constructor.getName());
    }
}

Field[] intFields = int.class.getFields();

if(intFields.length == 0) {
    System.out.println("No fields.");
}
else {
    for(Field field: intFields) {
        System.out.println(field.getName());
    }
}

答案 2

如果您运行

System.out.println(Modifier.toString(int.class.getModifiers()));

你得到

public abstract final

可能是因为你不能对它进行子类化 - 即最终的,并且你不能实例化它 - 即抽象。

来自 Oracle 的抽象方法和类

抽象类不能实例化,但它们可以被子类化。

事实是,它也是最终的,这意味着它不能是子类。