据我了解,以下代码应打印False
,但是当我运行此代码时,它打印的是True
。
来自Java文档:
如果整数参数包含abstract修饰符,则返回true, 否则为假。
public class Test{
public static void main(String[] args) {
System.out.println(Modifier.isAbstract(byte[].class.getModifiers()));
}
}
有人可以帮助我了解这种行为吗?
答案 0 :(得分:49)
Javadoc of int java.lang.Class.getModifiers()指定数组类型的某些修饰符应返回的内容(例如,final
修饰符必须为true
,而interface
修饰符必须为false
)。另一方面,它没有指定数组类型的abstract
或static
修饰符应该是什么,这意味着没有记录返回true
或false
的决定。在JDK中。因此,任何实现都可以选择返回true
或false
。
int java.lang.Class.getModifiers()
返回该类或接口的Java语言修饰符,以整数编码。修饰符由Java虚拟机的公共,保护,私有,最终,静态,抽象和接口常量组成;应该使用Modifier类的方法对它们进行解码。
如果基础类是数组类,则其公共,私有和受保护的修饰符与其组件类型的修饰符相同。如果此类表示原始类型或void,则其public修饰符始终为true,而其protected和private修饰符始终为false。 如果此对象表示数组类,原始类型或void,则其最终修饰符始终为true,其接口修饰符始终为false 。 其其他修饰符的值不受此规范确定。
修饰符编码在Java虚拟机规范表4.1中定义。
答案 1 :(得分:6)
可以在JLS 10.8. Class Objects for Arrays中找到有关此行为的提示:
每个数组都有一个关联的Class对象,与其他所有具有相同组件类型的数组共享。
尽管数组类型不是类,但每个数组的Class对象的行为就像:[snipped]
根据这种推理,数组不是“真实”类,因此它绝对不是具体的类。相同的逻辑适用于int.class
被认为是抽象的。
答案 2 :(得分:3)
abstract的定义是:
抽象类是不完整的类,或者被认为是不完整的类。
如果有一个像[]
这样的纯数组,那么由于没有提供组件类型,所以它确实是不完整的。
这将违反15.10.1. Array Creation Expressions的规范:
如果ClassOrInterfaceType不表示,则为编译时错误 可更改的类型。
它不仅表示可更改的类型,而且根本不表示任何类型。因此,不可能像创建抽象类一样创建[]
的实例。
由于没有纯数组[]
,这只是一种推测。此外,返回了byte[]
的修饰符。仍然保留Eran所示的规范。
答案 3 :(得分:2)
我的移植是,将数组视为abstract
,因为数组是由JVM本身实例化的。
对于任何数组类型,都没有具体的类。
一个数组有一个contract defined by the JLS:
Cloneable
和Serializable
的实施方式但是除了语言本身之外,没有人可以实现这些目标,因为我们无法真正声明自己的实现。
答案 4 :(得分:2)
据我了解,getModifier()的Java语言规范是:
如果基础类是数组类,则其公共,私有 和保护的修饰符与其组件类型的修饰符相同。 如果此类表示原始类型或void,则其public修饰符 始终为true,并且其protected和private修饰符始终为 错误
现在,其其他修饰符的值不是由本规范确定的,例如摘要。
从JVMS表4.1-A:
ACC_ABSTRACT 0x0400声明为摘要;不得实例化。