Potresti trovarti nella posizione di pensare di rendere definitivo un metodo statico, considerando quanto segue:
Avere le seguenti classi:
class A {
static void ts() {
System.out.print("A");
}
}
class B extends A {
static void ts() {
System.out.print("B");
}
}
Ora il modo "corretto" per chiamare questi metodi sarebbe
A.ts();
B.ts();
che risulterebbe AB
ma potresti anche chiamare i metodi sulle istanze:
A a = new A();
a.ts();
B b = new B();
b.ts();
che risulterebbe AB
anche.
Ora considera quanto segue:
A a = new B();
a.ts();
che verrebbe stampato A
. Questo potrebbe sorprenderti visto che stai effettivamente avendo un oggetto di classe B
. Ma poiché lo chiami da un riferimento di tipo A
, chiamerà A.ts()
. Puoi stampare B
con il seguente codice:
A a = new B();
((B)a).ts();
In entrambi i casi l'oggetto che hai è effettivamente di classe B
. Ma a seconda del puntatore che punta all'oggetto, chiamerai il metodo da A
o da B
.
Supponiamo ora che tu sia lo sviluppatore della classe A
e desideri consentire la sottoclasse. Ma vuoi davvero il metodo ts()
, ogni volta che viene chiamato, anche da una sottoclasse, che fa quello che vuoi che faccia e non sia nascosto da una versione della sottoclasse. Quindi potresti farlo final
e impedire che venga nascosto nella sottoclasse. E puoi essere certo che il seguente codice chiamerà il metodo dalla tua classe A
:
B b = new B();
b.ts();
Ok, ammettetamente che è in qualche modo costruito, ma potrebbe avere senso per alcuni casi.
Non dovresti chiamare metodi statici sulle istanze ma direttamente sulle classi, quindi non avrai quel problema. Anche IntelliJ IDEA, ad esempio, ti mostrerà un avviso, se chiami un metodo statico su un'istanza e anche se rendi finale un metodo statico.