Variablen Coding Convention

kaoZ

Top Contributor
Kleine Frage in die Runde , angenommen ihr habt folgenden Source Code

Java:
public class Foo {
	
	private String anExample;
	
	public Foo() {
		// TODO Auto-generated constructor stub
	}
	
	public String getExample(){
		return this.anExample;
	}
}

Nutzt ihr dann eher this. um auf die Variable zuzugreifen oder direkt den Getter ?

Ich sehe in fertigem Source Code oft beide Versionen , gibt es da irgendwelche Converntions oder ist das Geschmackssache ?

(man muss halt nur bei einer Version bleiben, und nicht anfangen das ganze in einer Klasse zu vermischen....)

Ich meine z.B :

Java:
if (getExample().equals("Bla")) {
			
}

ist auch nicht unübersichtlicher als

Java:
if (this.anExample.equals("Bla")) {
			
}
 

Tobse

Top Contributor
Kommt stark auf den Wert an. Wenn der Getter eh nur den Wert zurückgiebt nehme ich
Code:
this
. Wenn der Getter die Rückgabe aber beeinflusst kommt es drauf an, für was ich den Wert brauche. Wenn der Kontext den bearbeiteten wert erfordert nehm ich logischerweise den Getter. Wenn aber der Kontext den puren wert erfordert wieder this.
Was ich bei Methoden mit mehr als 1-2 lokalen Variablen strikt vermeide ist, auf Klassenvariablen ohne
Code:
this
zuzugreiffen, einfach der Übersicht halber.
 

kaoZ

Top Contributor
Was ich bei Methoden mit mehr als 1-2 lokalen Variablen strikt vermeide ist, auf Klassenvariablen ohne
Code:
this
zuzugreiffen, einfach der Übersicht halber.

Joa , das ist klar , wird ja sonst ein völliges Chaos ^^

ich persönlich finde den Getter schon irgendwie übersichtlicher, habe aber bisher immer mit this. gearbeitet, hätte ja sein können das man sich das gleich aneignet wenn es irgendwelche Conventions dazu gibt.


wenn man den Getter nutzt kann man zudem eine Verwechslung mit Lokalen Variablen ja quasi ausschließen ;)
 

Tobse

Top Contributor
wenn man den Getter nutzt kann man zudem eine Verwechslung mit Lokalen Variablen ja quasi ausschließen ;)

Das stimmt völlig. Ich habe nur immer die (möglicherweise völlig unbegründete) Angst, dass durch das ständige Methoden-Aufrufen die Performance irgendwann in den Keller geht.

Java:
class Foo
{
    private int bar;
    public int getBar()
    {
        return bar; // hier ohne this weil es hier völlig klar ist, welches bar gemeint ist
    }
    public void doSomething()
    {
        // A
        getBar();
        // B
        this.bar;
    }
}
Hier kommen nach meinem Wissen für A 2-3 Opcodes (im Bytecode) mehr raus als bei B (gesetzt den Fall der Optimizer erkennt das nicht und entfernt den Aufruf).

Und bei komplexen Sachen bläht sich dann der Stack total auf. Und wenn ich an Java eines hasse dann ist es das hier:
Code:
java.lang.NullPointerException
    at ...
    at ...
    ... 3 more
Und der Fehler ist genau in den [c]3 more[/c].
 

kaoZ

Top Contributor
Naja die NPE bekommste doch aber nur wenn das Attribut nicht initialisiert ist, und das sollte ja nicht passieren da es sonst zu inkonsistenzen führt , ich dachte jetzt eher du hast Angst vor StackOverFlowExceptions ;D
 

Tobse

Top Contributor
Naja die NPE bekommste doch aber nur wenn das Attribut nicht initialisiert ist, und das sollte ja nicht passieren da es sonst zu inkonsistenzen führt , ich dachte jetzt eher du hast Angst vor StackOverFlowExceptions ;D

Nicht ganz. Du kennst ja das Prinzip: Gibst du Mist in den PC rein kommt auch wieder Mist raus. Sprich:
Wenn eine Methode an der Spitze eines Abstraktionsmusters versehentlich ein Null mitgiebt und das dann 30 Stack-Stufen weiter unten deswegen kracht steht das nicht in der Stack-Trace.
 

Natac

Bekanntes Mitglied
Ich nehme immer den Getter. Zum einen ist dies dann einheitlich, zum anderen kann ich somit das Attribut besser steuern. Wenn ich mir morgen nämlich überlege, dass ich das Attribut vielleicht berechnen möchte, muss ich das nur an einer Stelle tun (oder ne Ausschrift, debuggen, was auch immer). Würd das Attribut auch immer nur über den Setter setzen. Auch in der Klasse selbst.

Ausnahmen bilden vielleicht sehr einfache Klassen, die nur ein paar Zeilen Quellcode haben. Ansonsten würde ich immer dazu raten die Zugriffspunkte auf Klassenvariablen an nur einem Punkt zu bündeln. Und das sind eben Getter und Setter für das Attribut.

Das stimmt völlig. Ich habe nur immer die (möglicherweise völlig unbegründete) Angst, dass durch das ständige Methoden-Aufrufen die Performance irgendwann in den Keller geht.
Musst du nicht. Dein Compiler kann "Methode inlining", was im Byte-Code eh dazu führt, dass auf die Variable direkt zugegriffen wird und der Getter-Aufruf verschwunden ist. Da kannst du in einem Quellcode ruhig schön sauber den Getter nehmen. ;)
 
Zuletzt bearbeitet:

turtle

Top Contributor
Hier kommen nach meinem Wissen für A 2-3 Opcodes (im Bytecode) mehr raus als bei B
Das stimmt nicht. Der Code sieht so aus:
Java:
    public void doSomething() {
	// A
	int xA = getBar();
	// B
	int xB = this.bar;
    }
Code:
  public void doSomething();
    Code:
       0: aload_0
       1: invokevirtual #21                 // Method getBar:()I
       4: istore_1
       5: aload_0
       6: getfield      #18                 // Field bar:I
       9: istore_2
      10: return
 

Androbin

Bekanntes Mitglied
Genau genommen kann man das "this.*" auch weglassen, sofern es keine gleichnamige Variable im Konstruktoren/Methoden-Kopf gibt :applaus:
 

mad2man

Mitglied
Java:
package varaiblendemo;

/**
 *
 * @author mad2man
 */
public class VariablenDemo
{

    private int var;

    public VariablenDemo()
    {
        //do something
        this.var = 100;
    }

    public String getVarFormatted()
    {

        return String.format("#03%d", this.var);
    }

    public int getVar()
    {
        return this.var / 2;
    }

    public void doSomeThing()
    {
        // der getter würde nur ein unnötiger aufruf sein.
        // mein beispiel getter manipuliert den wert 
        int test = this.var ;
    }

}
 
Zuletzt bearbeitet:

turtle

Top Contributor
Ich stimme Natac voll zu.

Es ist sinnvoll(er) den getter zu benutzen, weil man dann, sollte man im getter() Dinge tun, beispielsweise Validierungen, sicher ist, das diese IMMER getan werden. Sonst muss man den Code suchen, ob da noch direkte Zugriffe gemacht werden.

Und einer der Gründe für OOP ist doch wohl, das man Encapsulation gut findet, oder?

Und ob der Methodenaufruf überhaupt Nachteile hat, ist schwierig zu beantworten. Denn auch hier hat Natac richtig erwähnt, das die JVM entscheiden kann, den Aufruf zu optimieren und den Code stattdessen zu in-linen. (Eine der Gründe warum Micro-Benchmarks in Java so schwierig sind).
 
Zuletzt bearbeitet:

Tobse

Top Contributor
Das stimmt nicht. Der Code sieht so aus:
Java:
    public void doSomething() {
	// A
	int xA = getBar();
	// B
	int xB = this.bar;
    }
Code:
  public void doSomething();
    Code:
       0: aload_0
       1: invokevirtual #21                 // Method getBar:()I
       4: istore_1
       5: aload_0
       6: getfield      #18                 // Field bar:I
       9: istore_2
      10: return

Und durch
Code:
invokevirutal
laufen dann nochmal
Code:
getfield
und
Code:
return
. Aber Danke für das Beispiel: Hier hat der Compiler auch keine Optimierung vorgenommen. Sprich der direkte zugriff ist in performance-kritischem boilerplate-code zu empfehlen.

Was das ersetzen der direkten Zugriffe angeht wenn der Getter komplexer wird: Refactoring FTW.
 
Zuletzt bearbeitet:

nvidia

Bekanntes Mitglied
[...] Sprich der direkte zugriff ist in performance-kritischem boilerplate-code zu empfehlen.
[...]

Das kannst du überhaupt nicht beurteilen, da der JIT zur Laufzeit auch noch ein wenig mitzureden hat. Sind die Methoden klein, werden sie nicht überschrieben etc. wird der JIT heiße Methoden mit ziemlich hoher Wahrscheinlichkeit inlinen.

Um zu sehen was der JIT so treibt kann man ein Programm mal mit XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining starten und auf der Konsole beobachten was so getrieben wird.
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben