从Java内部构件角度继承最终类

从Java内部构件角度继承最终类,java,Java,当声明一个类为final时,我们不能继承这个类,我的问题是为什么从java内部构件的角度来看 我假设同样的原则也适用于方法和实例。 它是否也与类装入器有关?到底是谁在阻止我覆盖它 这与Java内部结构无关 将类声明为final的目的是防止它被子类化 我的问题是在宣布最终结果时地下发生了什么 嗯。。。当一个类被声明为final时,类文件中会设置一个标志来说明这一点。如果然后尝试加载一个声称是最终类的子类的类,则类加载器将抛出VerifyError异常。检查在类加载器中完成。定义类。。。方法。。。它

当声明一个类为final时,我们不能继承这个类,我的问题是为什么从java内部构件的角度来看

我假设同样的原则也适用于方法和实例。
它是否也与类装入器有关?到底是谁在阻止我覆盖它

这与Java内部结构无关

将类声明为final的目的是防止它被子类化


我的问题是在宣布最终结果时地下发生了什么

嗯。。。当一个类被声明为final时,类文件中会设置一个标志来说明这一点。如果然后尝试加载一个声称是最终类的子类的类,则类加载器将抛出VerifyError异常。检查在类加载器中完成。定义类。。。方法。。。它们也是最终的,所以正常的程序不能干扰它们

出于Java安全原因,类文件验证的这一方面需要无懈可击。如果不是这样,您可能会通过欺骗可信代码使用字符串的可变子类型,在Java安全沙箱中造成混乱

Java编译器还检查您是否没有扩展最终的类,但是您可以通过手动创建.class文件来破坏它。因此需要进行加载时间检查

到底是谁在阻止我覆盖它


实际上,它是类加载器。请参见上文。

与JVM或内部结构没有任何关系。我不确定您的意思是什么,这只是一个编译问题,因为您违反了规则

如果我认为自己是一个Java编译器,那么在解析代码中的标记之后,我将只是四处寻找逻辑错误语义分析,例如循环继承方案。当我看到有人试图延长最后一节课时,我要去火箭筒。就这样。无需唤醒大老板、JVM或任何其他内部成员,因为程序首先无法正确编译


如果您想知道编译器内部的工作方式,请考虑当编译器解析代码时,它会创建并填充自身内部的一些结构,以便进行错误检查和字节码转换。在一个简化的场景中,假设附加到类的final关键字只是在附加到类的其中一个结构中设置了一个字段。在语法分析之后,编译器继续进行逻辑语义分析,并检查是否有疯子试图扩展最后一个类。即使在继承图中进行野蛮搜索也可以实现这一点。如果一门课是最后一门课,但仍然有孩子,停下来通知疯子。这个问题不会比编译器更复杂。

让我们从元素上看一下,当您将一个变量声明为final时,您这样做是因为您不希望以后由于任何原因更改该变量的值,对吗

好吧,假设你同意。同样的原则也适用于类

让我们这样看:为什么要继承一个类?可能是因为您想访问类的属性和她的行为方法,对吗?一旦您继承了这些属性和行为,您就有权修改可访问的行为以满足您的精确需求,而无需重新实现所有其他行为。这就是继承的价值和力量

因此,将类声明为final意味着您不希望任何人修改该类的任何行为。您试图声明希望使用您的类的人应该按原样使用它

因此,任何修改最终类的尝试都是不合逻辑的,应该被视为错误

例如。 想象某人是否应该能够继承您的最终身份验证类并修改实际的身份验证行为方法。这应该是一个安全桥,因为它可能会影响您将类设置为final的原因

因此,这是一种设计实践


我希望这有点道理?

这根本不是我的问题,我的问题是在声明最终类/方法/变量时内部发生了什么,是谁阻止您重写它?这是一个关于Java语言定义的问题,以及为什么该语言具有特定特性的基本原理。本论坛主要用于语言的应用,而不是语言定义的元讨论。为了得到满意的答案或评论,你需要另找一个地方进行这样的讨论。@erstwhilleii还有其他地方需要我发布它吗?顺便问一下,一种具有特定特征的语言将被实现以坚持这些特征。。。这些特征不是来自于实现,而是来自于这些特征。@erstwilleii理解了,这就是为什么我问我
我的问题是,在宣布最终结果时,地下到底发生了什么,我知道这就是它要做的。如果试图声明final的子类,编译器将防止并生成编译时错误class@SubhrajyotiMajumder在这种情况下,是否有与类装入器相关的内容?就像在静态方法/变量上声明类加载器在创建同一类的实例之前正在创建它们一样?@subbrajyotimajumder-实际上,真正重要的检查是在加载时通过JVM内部的验证代码完成的。