在对Java类型进行一些反思的过程中,我遇到了一个我不理解的奇怪问题。
检查int
的修饰符将返回public
、abstract
和final
。我理解public
和final
,但是在原始类型上存在abstract
对我来说并不明显。为什么会这样呢?
编辑:我不是在反思Integer
,而是在反思int
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
发布于 2012-11-01 23:51:42
如果你运行
System.out.println(Modifier.toString(int.class.getModifiers()));
你会得到
public abstract final
可能是因为你不能子类化它--也就是final,你也不能实例化它--也就是抽象。
来自甲骨文的Abstract Methods and Classes
抽象类不能实例化,但可以子类化。
事实是它也是最终的,这意味着它不能是子类。
发布于 2012-11-02 00:08:54
根据JLS 8.1.1.1 - Abstract Classes的说法
抽象类是不完整的或被认为是不完整的类。
根据定义,不能有int.class
的实例。你不能编译这种代码:
int a = new int();
没有用于int
的构造函数。没有创建任何对象。int.class
甚至没有扩展Object
。如果您运行以下代码行,您将得到null
作为结果。
System.out.println(int.class.getSuperclass());
因此,因为您永远不可能拥有真正的int.class
实例,所以根据定义,它是abstract
。此外,根据Integer API,Integer.TYPE
字段(保存int.class
)是一个只表示原始类型的类。
下面的代码证明了这一点:
int a = 4;
System.out.println(int.class.isInstance(a));
这将返回false
。
因此,正如Integer
应用编程接口中所述,int.class
很可能只是在系统中用于表示目的。还有一个void.class
类型,但没有null.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());
}
}
发布于 2012-11-02 03:22:40
来自JVM规范:
抽象类是不完整的类,或者认为是不完整的。只有抽象类才能具有抽象方法,即已声明但尚未实现的方法。
如果一个类的定义是完整的,并且没有所需的子类或> required,则可以将其声明为final。因为最终类没有任何子类,所以最终类的方法不能在子类中被重写。一个类不能同时是最终的和抽象的,因为这样的类的实现永远不可能完成。
根据specifications的说法,一个类不能同时是抽象的和最终的。但是,JVM似乎没有将原始类型视为类,这在技术上是正确的,因为原始类型是而不是类,并且由JVM(使用Class getPrimitiveClass(const char *name)
)提供给语言运行时。
所以int
和其他所有的原始类型,
> 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
的理论是因为,它们被认为是不完整的()。
https://stackoverflow.com/questions/13180600
复制相似问题