# Automatisch final schreiben lassen



## Rudolf (17. Apr 2012)

Hi,

in meinem Studium habe ich gelernt, alles möglichst private und final zu programmieren.

Eclipse unterstützt praktische Save Actions, in denen private Fields, Parameter usw finalisiert werden können, d.h. Eclipse fügt final zu den einzelnen Items hinzu.

Ich möchte gerne, dass final überall steht wo es nur geht, bis ich selber das final rausnehme, weil eine Methode oder ein Parameter überschrieben werden soll. 

Eclipse erkennt auch automatisch, wo Parameter oder Fields überschrieben werden, sodass es dann kein final hinzufügt. Das möchte ich gerne bei Klassen, bei allen Methoden, bei private Methods usw. auch.

D.h., Eclipse soll sehen, ob irgendwo meine Klasse erweitert wird und eine Operation überschrieben werden soll, sodass es dann kein final in die Methodensignatur hinzufügt.

Kann man das in Eclipse irgendwo einstellt, oder gibt es ein bekanntes Plugin zu dieser Frage?


----------



## Andgalf (17. Apr 2012)

Ich habe zwar leider keine Lösung für dein Problem

aber:



Rudolf hat gesagt.:


> in meinem Studium habe ich gelernt, alles möglichst private und final zu programmieren.



Ich halte so restriktive Aussagen immer für gefährlich. Außerdem habe ich mich schon das Ein oder Andere mal darüber geärgert, dass ich bei Fremdbibliotheken nicht überschreiben konnte, weil jemand meinte er müsse alles final machen.

Ich persönlich würde dir also davon abraten. Ich mache immer genau dann etwas final, wenn ich mir sicher bin, dass es problematisch ist es zu überschreiben .... sonst nicht.

BTW. Wenn Du Frameworks wie z.B. JPA/Hibernate verwendest führt die "final save action" bei member Variablen auch zu problemen, weil evtl. Änderungen dann ggf. nicht persistiert werden.


----------



## SlaterB (17. Apr 2012)

mal ganz praktisch gefragt: wie soll Eclipse das machen oder worum geht es genau?

zum einen tippst du doch selber Code, soll Eclipse da eine Art Autocomplete machen?
'public void methodeY()' getippt und Eclipse fügt einfach so 'final' ein? tippe doch selber gleich guten Code..
oder geht es nur um gewissen automatisch erstellten Code?

ein zweiter wichtiger Punkt:
Vererbung usw. ist nicht mit einem Fingerschnippen da, sondern entsteht doch im Laufe der Zeit,
zuerst ist sicher nur die Grundklasse X vorhanden, vielleicht vorher noch ein Interface,
in X steht dann sicherlich sicherheitsorientiert irgendwo 
'public final void methodeZ()'
denn noch kann niemand wissen, nichtmal per Programmierer selber, dass morgen vielleicht eine Unterklasse kommt

am nächsten Tag ist es dann so weit, eine Unterklasse Y auch mit methodeZ() wird geschrieben, auf welche Weise auch immer,
was ist jetzt dein Ziel? soll Eclipse stillschweigend der finalen Methode in X das final wegnehmen?
das doch wohl sicher nicht, das wäre ja eine riesige Hintergrund-Fehlerquelle, kein final wäre sicher wenn automatisch entfernt,

welches andere Ziel magst du haben? methodeZ() in Y final machen ist ja Standard,  hat mit der Vererbungssituation zu X wenig zu tun

anderseits überhaupt erst jetzt (automatisch) über final oder nicht in X nachzudenken ist doch ziemlich spät 
wenn die Information, dass es überhaupt eine Unterklasse Y gibt, erst wer weiß wann kommt?


----------



## maki (17. Apr 2012)

Finde finale Felder in Objekten sind eine gute Sache, Save Actions eignen sich dafür, weil es automatisch passiert 
Wenn du speicherst bevor du Code hast der die Variable nach der Initialisierung verändert, geht Eclipse davon aus dass es sich um final Variablen handelt.



> Ich halte so restriktive Aussagen immer für gefährlich. Außerdem habe ich mich schon das Ein oder Andere mal darüber geärgert, dass ich bei Fremdbibliotheken nicht überschreiben konnte, weil jemand meinte er müsse alles final machen.
> 
> Ich persönlich würde dir also davon abraten. Ich mache immer genau dann etwas final, wenn ich mir sicher bin, dass es problematisch ist es zu überschreiben .... sonst nicht.


Theoretisch ist es ganz klar: Umgekehrt wird ein Schuh daraus.
Klassen/Methoden sollten nur dann nicht final sein, wenn sie extra für Vererbung konzipiert wurden.

In der Realität verursacht das aber gerne mal Probleme, zB. beim Mocken von Klassendie finale Methoden haben.
Finale felder sind gar nicht final wenn man zB. ein DI Framework mit Fieldinjection einsetzt, oder das ORM die Felder direkt setzt, dann soll man keinesfalls final verwenden.



> BTW. Wenn Du Frameworks wie z.B. JPA/Hibernate verwendest führt die "final save action" bei member Variablen auch zu problemen, weil evtl. Änderungen dann ggf. nicht persistiert werden.


Mit reflection kann man finale Felder "umbiegen", ist aber gefährlich, weil die final Sematik nicht mehr eingehalten wird: von Finalen felder sehen alle Threads denselben Wert, durch tricksen wird das ausgehebelt.


----------



## Andgalf (17. Apr 2012)

maki hat gesagt.:


> Mit reflection kann man finale Felder "umbiegen", ist aber gefährlich, weil die final Sematik nicht mehr eingehalten wird: von Finalen felder sehen alle Threads denselben Wert, durch tricksen wird das ausgehebelt.



Ja ich weiß, dass man das mit Reflection umbiegen kann. Aber Hibernate macht das nicht und von daher habe ich mir mit der save action in Eclipse schon öfter mal Bugs eingebaut.


----------



## maki (17. Apr 2012)

> Ja ich weiß, dass man das mit Reflection umbiegen kann. Aber Hibernate macht das nicht und von daher habe ich mir mit der save action in Eclipse schon öfter mal Bugs eingebaut.


Klar macht Hibernate das auch bei Field Access, und das ist auch der Grund für den Fehler, final ist schlicht falsch wenn Felder nachträglich geändert werden (eben durch Reflection Trickserei).


----------



## SlaterB (17. Apr 2012)

Andgalf hat gesagt.:


> Aber Hibernate macht das nicht und von daher [..]


kann man etwa in Eclipse diese Stelle nicht überschreiben und umbauen, ist das final gesetzt worden? :lol:


----------



## Andgalf (17. Apr 2012)

maki hat gesagt.:


> Klar macht Hibernate das auch bei Field Access



Da ich eigentlich immer an den Gettern annotiere gehe ich davon aus, das Hibernate dann auch nicht Field Access verwendet ... Da magst Du also Recht haben.

Jedenfalls habe ich den Effekt beobachtet, dass Änderungen nicht persistiert werden.


----------



## Landei (17. Apr 2012)

Bedenke bitte auch, das [c]final[/c]-Felder beim Deserialisieren nicht gefüllt werden können, solche Klassen also de facto nicht serialisierbar sind.

Siehe z.B. java serialization and final fields - Stack Overflow


----------



## maki (17. Apr 2012)

Andgalf hat gesagt.:


> Da ich eigentlich immer an den Gettern annotiere gehe ich davon aus, das Hibernate dann auch nicht Field Access verwendet ... Da magst Du also Recht haben.
> 
> Jedenfalls habe ich den Effekt beobachtet, dass Änderungen nicht persistiert werden.


Getter zu Annotieren ist nicht die empfohlene Art (offiziell seit JPA 2.0), man wäre einerseits gezwungen für alle Properties Getter & Setter zu machen (sind dann keine POJOs mehr), andererseits will man beim Persisitieren ja den internen Zustand eines Objektes speichern, alles in allem ist Field Access der besserere/sauberere Weg IMHO, man darf halt nur nciht auf die Idee kommen die Felder final zu deklarieren.


----------



## SlaterB (17. Apr 2012)

@Landei
inwiefern funktioniert das nicht?

mein eigenes Programm geht und erste Suchergebnisse sprechen auch nicht unbedingt dagegen
java serialization and final fields - Stack Overflow

nur bei Security-Einstellungen mit Problemen?


```
public class Test  implements Serializable {
    final int x;

    public Test(int x)  {
        this.x = x;
    }

    public static void main(final String[] args)     throws Exception    {
        Test t = new Test(44);

        Test t2 = (Test)clone(t);
        System.out.println(t2.x);
    }

    public static Object clone(Object copyObject)    throws Exception   {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(copyObject);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        Object deepCopy = ois.readObject();
        return deepCopy;
    }
}
```


----------



## Andgalf (17. Apr 2012)

maki hat gesagt.:


> Getter zu Annotieren ist nicht die empfohlene Art (offiziell seit JPA 2.0), man wäre einerseits gezwungen für alle Properties Getter & Setter zu machen (sind dann keine POJOs mehr), andererseits will man beim Persisitieren ja den internen Zustand eines Objektes speichern, alles in allem ist Field Access der besserere/sauberere Weg IMHO, man darf halt nur nciht auf die Idee kommen die Felder final zu deklarieren.



Ok, erstmal danke für den Hinweis. Werde das mit der Getter Annotation nochmal überdenken atm. ist das allerdings noch Konvention im Projekt.

Aber die Aussage "(sind dann keine POJOs mehr)" verstehe ich nicht, warum sollten es dann keine Pojos mehr sein?


----------



## Landei (17. Apr 2012)

Oh, habe ich wohl mit dem [c]final transient[/c] Problem velwechsert.


----------



## maki (17. Apr 2012)

> Aber die Aussage "(sind dann keine POJOs mehr)" verstehe ich nicht, warum sollten es dann keine Pojos mehr sein?


POJOs, "Plain Old Java Objects", damit ist gemeint:
Keine Interfaces implementieren, keine zus. Konventionen einzuhalten (Getter/Setter/Konstruktoren).
JavaBeans sind keine POJOs!

POJOs kannst du dir als "freestyle" Objekte vorstellen, die eben nix spezielles vorraussetzen.

Plain Old Java Object - Wikipedia, the free encyclopedia


> The term "POJO" is mainly used to denote a Java object which does not follow any of the major Java object models, conventions, or frameworks.


----------



## SlaterB (17. Apr 2012)

ein POJO mit setter ist nebenbei dann auch final-frei oder?
keine Ahnung ob ich damit wem wiederspreche, wer jetzt wo bei Hibernate final wollte, schlecht fand, Umwege sah usw.
nur angemerkt


----------



## Andgalf (17. Apr 2012)

maki hat gesagt.:


> keine zus. Konventionen einzuhalten
> JavaBeans sind keine POJOs!


 Ah, ok. Hier war ich tatsächlich der fälschlichen Annahme unterlegen, das JavaBeans POJOs sind.


----------



## maki (17. Apr 2012)

Andgalf hat gesagt.:


> Ah, ok. Hier war ich tatsächlich der fälschlichen Annahme unterlegen, das JavaBeans POJOs sind.


Das liegt IMHO daran, dass die Literatur, Dokus und vor allem Marketing den Begriff POJOs oft falsch verwenden, bedeutet meisst nur "Keine EJB 2.x" oder schlimmer noch, "POJOs" wird fälschlicherweise als Synonym für "JavaBeans" verwendet...

Genaugenommen sind JavaBeans sogar nur Datenstrukturen, nicht Objekte.

@SlaterB,

Ja, eine JavaBean hat IMHO auch final-frei zu sein, liegt aber daran, dass man ja imer alles per Setter ändern können soll bein JavaBeans.


----------



## Rudolf (18. Apr 2012)

Hallo Leute,

ich habe gerade einen anderen Prof wegen der Frage gefragt. Sein Profkollege hat das so formuliert, weil die Methoden in Java oft überschrieben werden und ohne eine Annotation (die auch oft vergessen wird) sieht man nur sehr umständlich ob Methoden überschrieben wurden und man sich daher eine final-Schreibweise angewöhnen sollte. Man kann sich die Override-Annotation aber auch automatisch über die Save Actions von Eclipse einstellen.

Von daher hat sich das Thema für mich erledigt.


----------



## Andgalf (18. Apr 2012)

Rudolf hat gesagt.:


> weil die Methoden in Java oft überschrieben werden und ohne eine Annotation (die auch oft vergessen wird) sieht man nur sehr umständlich ob Methoden überschrieben wurden



Extrem schwaches Argument imho.

Aber das automatische setzen von @Override halte ich für sinnvoll, habe es eigentlich auch immer aktiviert.


----------



## SlaterB (18. Apr 2012)

automatischen Setzen bringt nichts (jedenfalls einmaliges, weiß nicht wie das auf Dauer agiert), 
weil das immer manuell entfernt/ in fremden Code nicht vorhanden sein kann,
also bringt nichts an Sicherheit, als Spielerei zur Einsparung von Tipparbeit meinetwegen

wichtig ist allein eine Warning, wenn eine Methode eine andere überschreibt und die Annotation fehlt,
dann hat man immer ein Info, entweder die Annotation oder die Warning (hmm, zwei verschiedene Arten ist ja auch nicht so toll..)

dann kann man gegebenenfalls selber mit Intelligenz im Kopf reagieren, 
soll die Annoation ran?
sollte die Obermethode nicht eher final sein und die Untermethode anders dran kommen? usw.


----------

