Scoping - nützlich?

Status
Nicht offen für weitere Antworten.

Geekhead

Mitglied
Hallo, eigentlich nur eine kurze Frage.
Ich hab grad in "Thinking in Java" etwas über Scoping gelesen.

Meine Frage ist nun diese, bringt das tatsächlich was in Java mit Scoping zu arbeiten?
Hab irgendwo noch nirgends gelesen/gesehn das jemand etwas gescoped hat?

Von der Theorie her klingt es logisch etwas zu scopen, so das tatsächlich nur eine
für die Kürze benötigte Variable direkt wieder freigegeben wird im Speicher.

Aber wie sieht es in der Praxis aus?
 
B

bygones

Gast
genauso... warum eine variable global machen wenn sie nur lokal gebraucht wird.

meiner ansicht nach sollte man sie eben genau deshalb scopen, damit Java dann den Speicher frei raeumen kann, sobald der entsprechende Block abgearbeitet wurde. Liegt die Variable ausserhalb des eigentlichen scopes wird diese noch behalten, obwohl schon nicht mehr gebraucht....
 

mikachu

Top Contributor
bei jeder for( int i = .... ) legst du nen bereich für die variable i an. denn diese ist nur für die schleife gültig.

sinnvoll ist es auch, damit du dich nicht mit den variablen in größeren klassen mehr rumschlagen musst.
 

Geekhead

Mitglied
Doofes Beispiel:


Code:
{
String msg = "Bla";
System.out.println(msg);
}

Wenn ich msg wirklich nur für diese Ausgabe benötige und kein anderes mal, dann auf alle Fälle scopen, ok :)

For Schleifen scopen von alleine?
Sicher?

Nach ner For-Schleife ist das i doch noch auf dem letzten Wert, das würde bedeuten das es nicht gescoped ist,
da i noch verfügbar?
 

mikachu

Top Contributor
Code:
      for( int i = 0; i < 10; ++i );
      System.out.println( i );

Meldung: i cannot be resolved.
 
B

bygones

Gast
probier mal folgendes zu kompilieren
Code:
for(int i = 0; i < 10; i++) {
 // mach irgendwas
}
System.out.println(i);
manche fragen lassen sich durch einfaches ausprobieren testen...
 

Geekhead

Mitglied
Es tut mir Leid... bei anderen Sprachen ist es eben der Fall das i nach der Schleife verfügbar ist...

Ich versuche mehr professionalität in dem Anfängerforum an den Tag zu legen...

Trotzdem danke für die Infos
 

mikachu

Top Contributor
wenn du explizit die laufvariable vor der schleife definierst, ist diese auch nach der schleife noch gültig... so, wie das in manchen anderen sprachen gemacht wird/werden muss.
 
B

bygones

Gast
nicht angegriffen fuehlen (auch wenn das hier nicht das anfaenger forum ist *g).

es ist nur so, dass man manches eben einfach und schnell durch selbst ausprobieren loesen kann... man lernt dadurch meiner ansicht nach besser als wenn es manche einen so hinwerfen !
 

Geekhead

Mitglied
deathbyaclown hat gesagt.:
nicht angegriffen fuehlen (auch wenn das hier nicht das anfaenger forum ist *g).

es ist nur so, dass man manches eben einfach und schnell durch selbst ausprobieren loesen kann... man lernt dadurch meiner ansicht nach besser als wenn es manche einen so hinwerfen !

Schande über mich... bin im Topic verrutscht :D


Also nochmals danke euch zwei
 

-frank

Bekanntes Mitglied
Geekhead hat gesagt.:
Code:
{
String msg = "Bla";
System.out.println(msg);
}

Wenn ich msg wirklich nur für diese Ausgabe benötige und kein anderes mal, dann auf alle Fälle scopen, ok :)

also meiner ansicht nach ist das absolut unnötig. wenn deine methode zb. 20 zeilen lang ist, dann ist 20 zeilen später der scope sowieso aus. vielleicht gibst spezialfälle, wo aufgrund von synchronisation sehr lange gewartet werden muss und java in dieser zeit (und in diesem spezialfall) sehr viel speicher freigeben könnte, aber im normalfall hast du ein paar variablen die für ne millisekunde länger nicht von der garbage collection geschlöscht werden können. ich lasse mich gerne korrigieren, aber aus meiner sicht ist das absolut vernachlässigbar.

edit: ... also ich meine, was die performance angeht. wenn du zb in einem switch-statement verhindern willst, dass eine variable irrtümlich in einem späteren case verwendet werden kann, dann kann man das natürlich machen. also nix generell gegen solche scope-blöcke! aber ich würde mir nicht angewöhnnen, dies bei jeder zweiten variable zu machen.
 
B

bygones

Gast
ah das habe ich uebersehen... ja so spezielle Bloecke in einem Block (also Block in Methode) - das halte ich auch fuer unsinnig.

Diskutierbarer ist so etwas, wenn ein Objekt ausserhalb seines eigentlich scopes definiert wird:
Code:
AnyObject object = null;
for(int i = 0; i < 10; i++) {
 object = // irgendwas;
}
// kommt noch einiges, aber object wird nicht mehr gebraucht
 

-frank

Bekanntes Mitglied
deathbyaclown hat gesagt.:
Diskutierbarer ist so etwas, wenn ein Objekt ausserhalb seines eigentlich scopes definiert wird:

aber macht man das nicht gerade WEIL man die referenz danach noch braucht?

okay, sowas kann ich mir vorstellen:

Code:
...
{
int count = 0;
while (bedingung) {
// do something
..

count++;
}

system.out.println("Count: " + count)}
}

// count wird nicht mehr gebraucht
...

aber wenn das nicht ein spezieller fall ist, wo ich - aus welchen gründen auch immer - besonders hervorheben möchte, dass count nach dem println nicht mehr gebraucht wird, dann würde ich auch den block nicht machen. ich meine, was gewinnt man dadurch wirklich? der block lenkt IMO die aufmerksamkeit auf sich: "aha, was wird hier gemacht?" und in wirklich gehts aber nur darum, dass der count-scope möglichst kurz gehalten wird. also mich würde das irritieren (aber vielleicht hab ich auch zu wenig erfahrung und das ist absolut usus, keine ahnung)[/code]
 
B

bygones

Gast
-frank hat gesagt.:
deathbyaclown hat gesagt.:
Diskutierbarer ist so etwas, wenn ein Objekt ausserhalb seines eigentlich scopes definiert wird:

aber macht man das nicht gerade WEIL man die referenz danach noch braucht?
nein ich meine schon den fall, dass man danach KEINE referenz mehr braucht !

Es stehen hier zwei diskussion an
Code:
AnyObject object = null;
for(int i = 0; i < 10; i++) {
object = // irgendwas;
}
gegen
Code:
for(int i = 0; i < 10; i++) {
AnyObject object = // irgendwas;
}

1. Nutzt man, weil man sagt, dass dadurch weniger Speicher gebraucht wird, da eine Variable angelegt wird und die immer ueberschrieben. Dafuer definiert man die Variable ausserhalb des scopes...

2. definiert eine Variable auch genau nur dort, wo sie gebraucht wird, wird der Block (also die schleife) verlassen kann das objekt verschwinden, dafuer erschafft man sich (wahr.) immer neue objekte...

ich weiss nicht wie sehr die VM hier optimiert...
 

-frank

Bekanntes Mitglied
deathbyaclown hat gesagt.:
ich weiss nicht wie sehr die VM hier optimiert...

naja, es geht ja hier nur um referenzen. keine ahnung wie aussagekräftig das ist, aber:

Code:
public class Main {

    private static final int NUMBER_OF_TESTS = 20;
    private static final long NUMBER_OF_OBJECTS_TO_CREATE = 10000000L;

    public static void main(String[] args) {
        for (int numberOfTests = 0; numberOfTests < NUMBER_OF_TESTS; numberOfTests++) {
            long time = System.currentTimeMillis();
            test1();
            long timeNeeded = System.currentTimeMillis() - time;
            long time2 = System.currentTimeMillis();
            test2();
            long timeNeeded2 = System.currentTimeMillis() - time2;
            System.out.println("difference: " + (timeNeeded - timeNeeded2) + " (1: "
                + timeNeeded + ", 2: " + timeNeeded2 + ")");
        }
    }

    public static void test1() {
        Integer integer;
        String string;
        for (int i = 0; i < NUMBER_OF_OBJECTS_TO_CREATE; i++) {
            integer = new Integer(i);
            string = new String("test" + i);
            doSomething(integer, string); // damit es sicher nicht wegoptimiert werden kann
        }
    }

    public static void test2() {
        for (int i = 0; i < NUMBER_OF_OBJECTS_TO_CREATE; i++) {
            Integer integer = new Integer(i);
            String string = new String("test" + i);
            doSomething(integer, string); // damit es sicher nicht wegoptimiert werden kann
        }
    }

    public static void doSomething(Integer integer, String string) {
        if (string.equals(integer.toString())) {
            System.out.println("wird wohl nicht passieren.");
        }
    }
}

gibt mir:
difference: 47 (1: 3719, 2: 3672)
difference: 15 (1: 3687, 2: 3672)
difference: 15 (1: 3703, 2: 3688)
difference: -16 (1: 3687, 2: 3703)
difference: -15 (1: 3688, 2: 3703)
difference: -15 (1: 3688, 2: 3703)
difference: -1 (1: 3687, 2: 3688)
difference: 16 (1: 3703, 2: 3687)
difference: 15 (1: 3703, 2: 3688)
difference: 15 (1: 3703, 2: 3688)
difference: 0 (1: 3703, 2: 3703)
difference: -16 (1: 3687, 2: 3703)
difference: 1 (1: 3688, 2: 3687)
difference: 17 (1: 3704, 2: 3687)
difference: 0 (1: 3703, 2: 3703)
difference: 15 (1: 3703, 2: 3688)
difference: 0 (1: 3703, 2: 3703)
difference: 1 (1: 3688, 2: 3687)
difference: 0 (1: 3703, 2: 3703)
difference: -15 (1: 3688, 2: 3703)

weiß nicht ob man das so messen kann, aber mir scheint da kein signifikanter unterschied.
 

Evil-Devil

Top Contributor
Naja, solange man nicht im HEAP rumwerkelt kann man gerne Methode 2 nehmen. Bevorzugen tu ich Methode 1, da ich viel im HEAP arbeite und bei größeren Objekten ist der Overhead für die Erzeugung des Objekte wesentlich höher als bei der neureferenzierung.
 
S

SlaterB

Gast
von Objekt-Erzeugung ist nie die Rede, es geht nur um die Referenz
 
B

bygones

Gast
SlaterB hat gesagt.:
von Objekt-Erzeugung ist nie die Rede, es geht nur um die Referenz
wir diskutieren hier nun 2 sachen...

1. Referenzen und der Scope
2. wann wo wie Objekte instanzieren.

bisherige Diskussion ging ueber 1), Evil-Devil redet ueber 2)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben