为什么Java基本类型是';公共、抽象和最终修饰符?
在对Java类型进行反思的过程中,我遇到了一个我不理解的奇怪现象 检查为什么Java基本类型是';公共、抽象和最终修饰符?,java,reflection,Java,Reflection,在对Java类型进行反思的过程中,我遇到了一个我不理解的奇怪现象 检查int的修饰符将返回public、abstract和final。我理解public和final,但是在原语类型上存在abstract对我来说并不明显。为什么会这样 编辑:我不是在思考Integer,而是在思考int: import java.lang.reflect.Modifier; public class IntegerReflection { public static void main(final Str
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
如果反射到从抽象类继承的类中,然后尝试挖掘该实例的基类,则在抽象类中定义为抽象的属性将没有值,但它是类定义的一部分 举个例子:
public class absBase{
private string name;
private int ID;
public abstract int GetID();
}
public class concreteClass:absBase{
@Override
public int GetID(){
return ID + 1;
}
}
所以,如果您要反映absBase,并且查看GetID,那么它必须是抽象的,如果您查看concreteClass.GetID(),那么它将是公共的。
希望这对你有所帮助。如果你跑步的话
System.out.println(Modifier.toString(int.class.getModifiers()));
你得到
public abstract final
可能是因为你不能对它进行子分类,比如final,你也不能实例化它,比如abstract
从甲骨文的
抽象类不能实例化,但可以子类化
事实上,这也是它的最终手段,它不能是子类。根据:
抽象类是不完整或被认为不完整的类
根据定义,不能有int.class
的实例。您无法编译此类代码:
int a = new int();
int
没有构造函数。没有创建任何对象int.class
甚至不扩展对象
。如果运行以下代码行,结果将是null
System.out.println(int.class.getSuperclass());
因此,因为您永远不可能拥有int.class
的真实实例,所以根据定义,它是抽象的
。此外,根据,Integer.TYPE字段(保存int.class
)是一个仅表示基元类型的类
以下代码证明了这一点:
int a = 4;
System.out.println(int.class.isInstance(a));
这将返回false
因此,int.class
很可能仅用于系统中的表示目的,如Integer
API中所述。还有一个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());
}
}
int.class
也可以作为Integer.TYPE
访问,并且是表示基元类型int
的类实例
鉴于您无法实例化此类的对象(因为int不是实例,它们是基本类型),我认为将类型标记为abstract
是有意义的
目前,我在《尽管》中找不到这方面的参考。来自JVM规范:
抽象类是不完整的类,或认为不完整的类。
只有抽象类可以有抽象方法,也就是,
已声明但尚未实现的方法
如果一个类的定义是完整的,并且不需要或不需要任何子类,则可以将其声明为final。因为最后一节课从来没有
任何子类,最终类的方法都不能在
子类。类不能既是最终类又是抽象类,因为
这样一个类的实现永远无法完成
根据类的定义,类不能同时是抽象的和最终的。但是,JVM似乎没有将基元类型视为类,这在技术上是正确的,因为基元类型是而不是类,并且由JVM提供给语言运行时(使用类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规范中关于原语类型为什么是
抽象的理论是因为它们被认为是不完整的 可能这只是基本类
与普通类
不同的一个特殊标记
JVM代码实现:
mirror::Class* ClassLinker::InitializePrimitiveClass(ObjPtr<mirror::Class> primitive_class,
Primitive::Type type) {
Handle<mirror::Class> h_class(hs.NewHandle(primitive_class));
// public final static
h_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
h_class->SetPrimitiveType(type);
h_class->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
// ...
return h_class.Get();
}
mirror::Class*ClassLinker::InitializePrimitiveClass(ObjPtr primitive_类,
基元::类型(类型){
Handle h_类(hs.NewHandle(primitive_类));
//公开最终静态
h|U类->设置访问标志(kAccPublic | kAccFinal | kAccAbstract);
h_类->SetPrimitiveType(类型);
h_class->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
// ...
返回h_类。Get();
}
为什么Java基元类型的修饰符是公共的、抽象的和最终的
Class.getModifiers()的Java 11声明:
如果基础类是数组类,则其公共
、私有
和受保护
修饰符与其组件类型的修饰符相同。如果此类
表示基元类型或无效
,则其公共
修饰符始终为true,其受保护
和私有
修饰符始终为false。如果此对象表示数组类、基元类型或void
,则其final
修饰符始终为true,其接口
修饰符始终为false其其他修饰符的值不由本规范确定
因此javadoc指定基本类型为public
和final
。这是很直观的。这将是在这两种情况下作出选择的原因
从技术上讲,abstract