Let me say the following: when developing a language that is a tool like any other, you need to think in terms of pluses and minuses, and not just limit the tool, because we cannot see the real use cases that apply. By doing this, we can theoretically understand such decisions. Basically, the exercise asks another question.
Why should Thread be final?
Let me understand.
(I donโt include the backward compatibility argument, I personally donโt like it, because I think we should always focus on improving locally)
To discuss this issue, we need to understand the benefits of declaring a class as final or not.
Performance
Here TofuBeer said:
Virtual (overridden) methods are usually implemented through some kind of table (vtable), which ultimately is a pointer to a function. Each call method has the overhead associated with having to go through this pointer. when classes are marked final, then all methods cannot be overridden and the use of a table is no longer required - it's faster.
Some virtual machines (for example, HotSpot) can do something more reasonably and know when methods are not overridden and generate faster code as needed.
Security
The oracle is emphasized here :
Better to create security-friendly APIs. Attempting to modify security in an existing API is more complex and error prone. For example, creating a class final prevents a malicious subclass from adding finalizers, cloning, and overriding random methods.
There are also problems with invariants and confidential information . However, all security issues are project specific and not applicable to a tool that can be used in non-security scenarios.
Convenience
andersoj called this nice IBM article here :
final classes and methods can be significant inconvenience when programming - they limit your options for reusing existing code and expanding the functionality of existing classes. Sometimes a class is final for a good reason, for example, to ensure that the benefits of using the end results are respected, they must outweigh the inconvenience. Improving performance is almost always a bad reason to compromise on good object-oriented design principles, as well as improving performance with little or no effect, this is a bad compromise indeed.
So, from my point of view, if there is no strong benefit to setting the class as final, if the JVMs are able to do such performance optimizations, I would say that the gain is in a convenient argument.
Thus, we can extend the Thread class and do whatever we want with it, some initialization / finalization elements, such as logging, changing thread names, type of thread ... This is for you!