Tim Bant wrote:1) What is the point/purpose of a final inner class if you can't instantiate/extend it?
There would be no point. However, "final" does not prevent an inner class from being instantiated - it only prevents it from being extended. So there can be a point, if you do instantiate the class.
(There could also be a reason to have a utility class, containing only static methods, which is usually made uninstantiable by design. Though I've never seen a nested / inner utility class, and I can't think of a good reason to have one.)
Tim Bant wrote:2) Why is a private abstract inner class permitted? Surely this should indicate that its private, so immediately no extending of it?
1. A private class could still be visible and / or extended by other code
within the same top-level class.. The modified "private" only means private within the same top-level class. (In the example shown, there
is no other code in that same top-level class. But there could have been.)
2. More importantly, when you have a private class that extends a public class, and instance of the private class is still an instance of that public class - which means, it can be passed on to other code that has access to the public class. That outside code can't directly call any private method or private field that is only defined in the private class. But, it can call any public method of the public base class - which can be overridden in the private class, and so can involve methods and fields in the private class.
Here's a simple example:
Here the MysteryObject declaration is only visible inside MysteryObjectSupplier - it can't be seen or used by the MysteryObjectClient. The Client only knows that it's getting an Object of some kind. And yet, it still is able to call the toString() method, because that is public in the original Object declaration. And so it is able to execute the code of toString() inside MysteryObject, which also uses the private name and creationTime fields. So, even though the MysteryObjectClient only knows it's getting an Object, it's getting an Object that is actually a MysteryObject, with specific behavior and data fields that were in that private class.