Um hier auch noch meinen Senf dazuzugeben:
Selbst wenn man deine bereits genannte Fehlermeldung eins zu eins (selbst mit Rechtschreibfehlern) bei google eingibt kommt man zu mehreren Ergebnissen.
Bei mir ist der erste Treffer
problems-with-local-variable-scope-how-to-solve-it, direkt darunter sogar die logische Folgefrage:
difference-between-final-and-effectively-final
Im ersten Link sind in der als aktzeptiert markierten Antwort auch Quellen für weitere Recherchen verlinkt (zum Thema "Anonyme Klassen").
Wenn dein Englisch noch nicht so gut ist:
Gehe trotzdem die englischen Beiträge durch und übersetze dir das, was du nicht verstehst.
So kannst du nach und nach immer besser Englisch und musst immer weniger nachschlagen, bis du irgendwann gar nicht mehr nachschlagen brauchst.
Bis dahin: Es gibt auch genug deutsche Quellen.
Damit hier nicht nur gemeckert wird und um dich etwas zu erleuchten:
Du hast folgende Klassen:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
|
public class Test {
public static void main(String[] args) {
Person personInstance = new Person("Max", "Mustermann", 17);
whoAreYou(personInstance);
}
private static void whoAreYou(Person passedPersonInstance) {
passedPersonInstance.greetings();
}
}
|
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class Person {
protected String firstname;
protected String lastname;
protected int age;
public Person(String firstname, String lastname, int age) {
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
public void greetings() {
System.out.println("Hello, my name is "+firstname+" "+lastname+" and I'm "+age+" years old!");
}
}
|
Die Klasse "Person" ist in diesem Fall immer bekannt. Wenn du (oder der Compiler) wissen möchtest, was eine Person ausmacht und welche Methoden diese hat, dann kannst du das einfach in der entsprechenden .java (oder .class) Datei nachgucken.
Jetz aufpassen, damit es nicht zu Verwirrungen kommt!
Anonyme Instanz/Anonymes Objekt (das ist KEINE anonyme Klasse, dazu später mehr)
Damit man nicht jedes mal explizit eine neue Instanz definieren muss, kann man den Konstruktor auch direkt aufrufen.
Durch
|
Quellcode
|
1
|
whoAreYou(new Person("Erika Mustermann", 31));
|
Vorher hatten wir uns diese unter dem Variablennamen "personInstance" gespeichert. Auch wenn diese Instanz jetzt keinen Namen hat wird natürlich trotzdem ganz normal eine Instanz vom Typ "Person" erzeugt und der Methode übergeben. Hier ist zwar die Instanz anonym, stellt für den Compiler jedoch kein Problem dar, da die Klasse weiterhin genau
bekannt ist und er nachgucken kann.
Anonyme Klasse
Nun gibt es Situationen, da möchte man nicht jedes Mal eine neue .java Datei erstellen (zum Beispiel weil der Umfang gering ist, die Klasse nicht wiederverwendet werden soll o.ä.).
Zum Beispiel möchtest du eine Person haben, die sich auch mit ihren Hobbies vorstellt.
Natürlich könntest du eine "PersonWithHobbies"-Klasse erstellen, aber da du die nur in diesem einen speziellen Fall brauchst, ist dir das zu viel.
Nun geben dir die anonymen Klassen folgende Möglichkeit:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public static void main(String[] args) {
Person personInstance = new Person("Max", "Mustermann", 17);
whoAreYou(personInstance);
Person anonymousPerson = new Person("Arne","Anonymus", 29) {
private String[] hobbies = new String[] {"Dancing","Fishing","Programming"};
@Override
public void greetings() {
System.out.print("Hi, you can call me "+firstname+", my lastname is a secret! ");
listHobbies();
}
public void listHobbies() {
System.out.print("But my hobbies are ");
for (String hobby : hobbies) {
System.out.print(hobby + " ");
}
System.out.println();
}
};
whoAreYou(anonymousPerson);
}
|
Die Objektinstanz "anonymousPerson" wurde mit Hilfe einer anonymen Klasse erzeugt!
Du siehst:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
Person anonymousPerson = new Person("Arne","Anonymus", 29) {
private String[] hobbies = new String[] {"Dancing","Fishing","Programming"};
@Override
public void greetings() {
System.out.print("Hi, you can call me "+firstname+", my lastname is a secret! ");
listHobbies();
}
public void listHobbies() {
System.out.print("But my hobbies are ");
for (String hobby : hobbies) {
System.out.print(hobby + " ");
}
System.out.println();
}
};
|
Durch diese Deklaration wurde der Klasse "Person" ein Array mit Hobbies und eine Methode hinzugefügt, um diese Auszugeben.
Die Klasse "Person" hat diese Eigenschaft aber gar nicht. Dennoch ist offensichtlich eine Klasse entstanden, die trotzdem eine Person ist (sonst würde sie von der "whoAreYou"-Methode nicht entgegen genommen werden können) und diese Klasse erweitert.
Diese entstandene Klasse ist jedoch sonst nirgendwo definiert.
Es gibt keine .java Datei in der Ihre konkrete Definition stünde, ebenso gibt es keine .class Datei, in der der Compiler nachsehen könnte.. sie ist
anonym.
Auch schön ist (und genau das machst du dir bei deinem ActionListener zu Nutze), dass das ganze auch mit Interfaces funktioniert. Dieses definiert lediglich ein Verhalten (also Methoden).
Dem Compiler ist völlig Wurst welche Klasse es ist. Sobald sie den ActionListener implementiert und seine "actionPerformed"-Methode implementiert, es diese Klasse de Facto ein ActionListener.
Was passiert hinter der Bühne?
Du würdest auf exakt das gleiche Ergebnis kommen, wenn du statt der anonymen Klasse eine richtig implementieren würdest.
Also zum Beispiel:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class AnonymousPerson extends Person {
private String[] hobbies = new String[] {"Dancing","Fishing","Programming"};
public AnonymousPerson(String firstname, String lastname, int age) {
super(firstname, lastname, age);
}
@Override
public void greetings() {
System.out.print("Hi, you can call me "+firstname+", my lastname is a secret! ");
listHobbies();
}
public void listHobbies() {
System.out.print("But my hobbies are ");
for (String hobby : hobbies) {
System.out.print(hobby + " ");
}
System.out.println();
}
}
|
Aus diesem Grund dürfen die Properties der "Person"-Klasse übrigens auch nicht private sein, sonst könnten sowohl die anonyme, als auch die "AnonymousPerson"-Klasse nicht darauf zugreifen.
Java nimmt dir hier einige Arbeiten ab (bei Interfaces implementiert die anonyme Klasse dieses automatisch, der Konstruktor der Oberklasse wird einfach übernommen etc.)
Schlussendlich ist das lediglich syntaktischer Zucker.
Um dir zum Abschluss trotzdem nochmal auf die Finger zu klopfen:
Bleib an Themen dran, wenn du sie nicht verstehst.
Bei kleinsten Schwierigkeiten ständig alles fallenzulassen und etwas neues anzugehen hilft dir nicht weiter.
Wie von anderen bereits erwähnt:
Bei deinen Codebeispielen stimmen schon Punkte zu den Grundlagen nicht.
Programmieren ist nunmal nicht einfach und selbst wenn du es "kannst" wirst du dir an vielen Stellen immer wieder die Zähne ausbeißen.
Ich muss mich auch immer wieder in neue Frameworks/Libraries und neue Projekte reinarbeiten.
Nicht selten verbringt man Stunden damit Dinge auszuprobieren, Dokumentationen zu lesen und kleine Testprojekte zu erstellen, nur um dann festzustellen, dass der Ansatz doch nicht so gut war und wieder von vorne anzufangen.
Dein Alter ist egal und zu blöd bist auch nicht, wenn du etwas nicht sofort verstehst.
Vielleicht bist du einfach nur zu ungeduldig... denn wichtig ist nur eines: dranbleiben!
PS: So rein aus Interesse.. was hast du eigentlich für ein Buch? (Titel?)
Wenn dort solche Codeschnipsel (und dann noch ohne oder mangelhafter Erklärung) drin stehen würde ich das rituell verbrennen..
An den Rest:
Sollte ich etwas umständlich (oder sogar falsch
) erklärt haben, bitte korrigieren
Das Schreiben wurde durch Duschen, Essen und einem Telefonat unterbrochen x) Möglich, dass sich Fehler eingeschlichen haben