I think your question is more about static versus singleton. Being a final class is not relevant in this context since you cannot override a static method (you can of course define the same signature static method in the extension but this would be irrelevant because the biding will still be "static" in the sense that calling SuperClass.getMethod will always call the definition from SuperClass). This is a classic question and I am sure you can find it answered elsewhere. However, just to give you a short answer, I would say that using a singleton allows you to implement interfaces and pass around your singleton object like any other object.
Maybe I can explain, to whomever gave me -1, what I meant (I thought it was clear enough). The original question is about singleton vs final. But when he explains, he states clearly that he is going to use static methods. He doesn’t realize then that what makes the methods unique in the sense that they belong to a single class is the fact that they are static, and so are class methods instead of instance methods. Being final has no effect: the user can instantiate as many as he wants, it only prevents him from extending the class, which did not seem to me to be the true concern of who asked the question.
On the other hand, he clearly states that he will use static methods on his final class. This seems then to indicate he wants to make it a singleton by using static methods: this is a classic way of doing it, and the question of using static methods versus singleton has been asked before. See for instance Why use a singleton instead of static methods? or Difference between static class and singleton pattern?
When I then write about overriding a static method, I try to explain that static method are not really overridden in the sense that they are not involved in dynamic binding. To give an example, if you have class A with static method foo() and then class B extends class A and redefines static foo(), that’s OK. But calling foo() on an object obj will call the static method belonging to the type of obj, even if you assign it a different object at runtime (this is what I call static binding). In other words, if you declare “A obj = new B()” and call obj.foo() it will still call A.foo()
I don’t know if that explanation helps, I wish whoever gave me -1 explained why.