首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Java原语类型的修饰符是public、abstract和final?

为什么Java原语类型的修饰符是public、abstract和final?
EN

Stack Overflow用户
提问于 2012-11-01 23:46:30
回答 6查看 2.3K关注 0票数 22

在对Java类型进行一些反思的过程中,我遇到了一个我不理解的奇怪问题。

检查int的修饰符将返回publicabstractfinal。我理解publicfinal,但是在原始类型上存在abstract对我来说并不明显。为什么会这样呢?

编辑:我不是在反思Integer,而是在反思int

代码语言:javascript
运行
复制
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())));
    }
}

运行时的输出:

代码语言:javascript
运行
复制
int.class == Integer.class -> false
int.class modifiers: public abstract final
Integer.class modifiers: public final
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-11-01 23:51:42

如果你运行

代码语言:javascript
运行
复制
System.out.println(Modifier.toString(int.class.getModifiers()));

你会得到

代码语言:javascript
运行
复制
public abstract final

可能是因为你不能子类化它--也就是final,你也不能实例化它--也就是抽象。

来自甲骨文的Abstract Methods and Classes

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

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

票数 5
EN

Stack Overflow用户

发布于 2012-11-02 00:08:54

根据JLS 8.1.1.1 - Abstract Classes的说法

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

根据定义,不能有int.class的实例。你不能编译这种代码:

代码语言:javascript
运行
复制
int a = new int();

没有用于int的构造函数。没有创建任何对象。int.class甚至没有扩展Object。如果您运行以下代码行,您将得到null作为结果。

代码语言:javascript
运行
复制
System.out.println(int.class.getSuperclass());

因此,因为您永远不可能拥有真正的int.class实例,所以根据定义,它是abstract。此外,根据Integer APIInteger.TYPE字段(保存int.class)是一个只表示原始类型的类。

下面的代码证明了这一点:

代码语言:javascript
运行
复制
int a = 4;
System.out.println(int.class.isInstance(a));

这将返回false

因此,正如Integer应用编程接口中所述,int.class很可能只是在系统中用于表示目的。还有一个void.class类型,但没有null.class类型,这让我认为这主要是与反射一起使用的。不过,这只是一种猜测。

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

代码语言:javascript
运行
复制
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());
    }
}
票数 7
EN

Stack Overflow用户

发布于 2012-11-02 03:22:40

来自JVM规范:

抽象类是不完整的类,或者认为是不完整的。只有抽象类才能具有抽象方法,即已声明但尚未实现的方法。

如果一个类的定义是完整的,并且没有所需的子类或> required,则可以将其声明为final。因为最终类没有任何子类,所以最终类的方法不能在子类中被重写。一个类不能同时是最终的和抽象的,因为这样的类的实现永远不可能完成。

根据specifications的说法,一个类不能同时是抽象的和最终的。但是,JVM似乎没有将原始类型视为类,这在技术上是正确的,因为原始类型是而不是类,并且由JVM(使用Class getPrimitiveClass(const char *name))提供给语言运行时。

所以int和其他所有的原始类型,

代码语言:javascript
运行
复制
> a. Should be accessible from within the language: Make it `public` 
> b. Should not be extensible                     : Make it `final` 
> c. Should not be instantiated with `new`        : Make it `abstract`.

我从JVM规范中得出的关于原语类型为什么是abstract的理论是因为,它们被认为是不完整的()。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13180600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档