# Anfängerniveau - Instanzvariablen <identifier expected>



## gebbissimo (18. Januar 2008)

Hallo!

ich bin seit kurzem in Java eingestiegen aber habe noch Probleme mit dem Verständnis der Objekt-orientierten Programmierung, speziell den Instanzvariablen.
Trotz einiger Tutoriale steige ich aber immer noch nicht ganz durch und hoffe mir könnte jemand folgende Fragen beantworten. Hier ein Bsp-Programm:



```
public class Meer
{

public static void main ( String[] args )
  {
    String drop;
    
    drop = new String("nass");
    
    System.out.print("Der Tropfen ist" + drop + "");
}

}
```



1. Anscheinend kann ich die Instanzvariablen nur in einer Funktion [z.B. main()] deklarieren, denn sonst beschwert er sich immer mit <identifier expected>
Warum ist das so? Ansonsten kann ich Variablen doch auch direkt in der Klasse deklarieren?

2. Ich fange ja an mit "String drop", wobei String eine Klasse ist. Bei meinem Beispiel könnte ich ja auch "Meer drop" schreiben, weil Meer die Klasse ist.
Das bringt mir aber nur etwas, wenn ich auch einen Konstruktor Meer(..) definiert habe, oder?

3. Wofür dient genau die erste Zeile "String drop"?
Danach sage ich doch sowieso, dass drop ein neues Objekt der Klasse String (?) werden soll, ist dies nicht doppelt gemoppelt? 



Ich hoffe ihr könnt mir meine Fragen beantworten, ansonsten würde mich auch über einen aussagekräftigen Link freuen!

Dankeschön im Voraus


----------



## Matze (18. Januar 2008)

1. Außerhalb einer Methode (main() ist eine) muss es heißen:
	
	
	



```
String strText = "Hallo ich bin der Text";
```

2. Ja so ungefähr.

3. Mit 
	
	
	



```
Sting drop;
```
reservierst du speicher für eine Variable die als Inhalt ein Objekt der Klasse String enthält und mit 
	
	
	



```
drop = ...
```
initialisierst du die Variable. Auf deutsch du weißt ihr einen Wert bzw. ein spezielles Objekt zu. Dieses Objekt kann ja auch wo anders her kommen wie z.b.
	
	
	



```
drop = drop2;
```
und mit 
	
	
	



```
new String("bla");
```
 erzeugst du ein neues (new) Objekt einer Klasse.


----------



## gebbissimo (18. Januar 2008)

Hallo Matze

und danke für die blitzschnelle Antwort. Ich habe (vorerst  ) nur noch eine kurze Frage:

Wenn man die Variable wie du es bei 1. gemacht hast deklarierst, ist es dann noch eine Instanzvarable oder doch eine Klassenvariable?


----------



## Matze (18. Januar 2008)

Immer noch eine Instanzvariable.


----------



## Oliver Gierke (18. Januar 2008)

wobei 
	
	
	



```
new String("foo")
```
 ziemlicher Müll ist, da "foo" selbst ja schon eine Instanz von String ist und somit ein String Objekt unnötig erzeugt wird.


Gruß
Ollie


----------



## gebbissimo (23. Januar 2008)

Hallo,

nochmal vielen Dank an die bisherigen Antworten, mir ist ein neues Rätsel aufgetaucht, das ich nicht wirklich verstehe:



```
//Instanzvariablen
    private double[] polly;
    double[] zero = new double[0];
    
    
    
    //Konstruktor
    Polynom(double[] polly_in){
        polly = polly_in;
    }
       
    
    Polynom() {
        this(zero);        
        //this (new double[] {3.0});
    }
```



Ich hoffe mein Ziel ist deutlich, ich möchte bei 
	
	
	



```
Polynom()
```
 ein Objekt erzeugen mit der Länge 0, indem ich polly zero zuweise.
Ich weiß dass es mit "this(null)" geht, aber zum Verständnis möchte ich meinen Fehler finden.

Er beschwert sich mit "cannot reference zero before supertype constructor has been called". Wir hatten schon über super und Vererbung gesprochen, aber dies ist damit nicht gemeint, oder?




Erst hatte ich folgenden Versuch, bekam aber dann die Fehlermeldung "call to this must be first statement in constructor". Muss dies IMMER so sein?


```
//Konstruktor
    Polynom(double[] polly_in){
        polly = polly_in;
    }
       
    
    Polynom() {
        double[] zero = new double[0];
        this(zero);
        //this (new double[] {3.0});
    }
```



Zu jedem Bsp.: Meine Deklaration von zero ist aber richtig, oder?

Viele Grüße,
Chris


----------



## zeja (23. Januar 2008)

gebbissimo hat gesagt.:


> Ich hoffe mein Ziel ist deutlich, ich möchte bei
> 
> 
> 
> ...



Du vermischt hier zwei Sachen: 
double [] nullArray = null;
double [] zeroLengthArray = new double[0];

Während nullArray wirklich null also nichts ist (wenn du da was drauf aufrufen willst knallts ganz gewaltig) ist zeroLengthArray tatsächlich ein Array allerdings ohne Inhalt, also mit der Länge 0. Merke: Null ist ungleich 0.



gebbissimo hat gesagt.:


> Er beschwert sich mit "cannot reference zero before supertype constructor has been called". Wir hatten schon über super und Vererbung gesprochen, aber dies ist damit nicht gemeint, oder?



Das hat tatsächlich was mit Vererbung zu tun. Hier hats was mit der Initialisierungsreihenfolge zu tun und die ist wie folgt:
Wenn ein Objekt einer Klasse instanziiert wird, wird erstmal in der Vererbungshierarchie durch alle Oberklassen der aktuellen Klasse gegangen und deren Konstruktoren aufgerufen. Wenn kein super() angegeben ist, wird troztdem der Leere Konstruktor der Oberklasse aufgerufen (wenn diese keine Konstruktoren ohne Argumente hat wird man aufgefordert einen entsprechenden Konstruktor mit Argumenten aufzurufen).

Beispiel:

```
public class SomeSuperSuperClass {

	public SomeSuperSuperClass() {
		System.out.println("Konstruktor von: SomeSuperSuperClass");
	}

	public static class SomeSuperClass extends SomeSuperSuperClass {
		private String classString;
                private String instanceString = "instanceString";

		public SomeSuperClass(String someString) {
			// Hier steht kein super() aber es wird trotzdem
			// der Konstruktor von SomeSuperSuperClass aufgerufen
			this.classString = someString;
			System.out.println("Konstruktor von: SomeSuperClass");
		}

	}

	public static class SomeClass extends SomeSuperClass {

		public SomeClass(String someString) {
			super(someString);
			System.out.println("Konstruktor von: SomeClass(String)");
		}

	}

	public static void main(String[] args) {
		SomeClass clazz = new SomeClass("test");
	}instanceString

}
```

Ausgabe:

```
Konstruktor von: SomeSuperSuperClass
Konstruktor von: SomeSuperClass
Konstruktor von: SomeClass(String)
Konstruktor von: SomeClass()
```

Auch ohne den Aufruf von super() in SomeSuperClass wird der Konstruktor von SomeSuperSuperClass aufgerufen.

Nach dem Aufruf des Konstruktors von SomeSuperClass wird das Feld instanceString initialisiert.

Das Problem ist also wenn du zero in this(..) angeben willst, so rufst du den Konstruktor deiner eigenen Klasse auf, die ruft die Konstruktoren der Oberklassen auf, tut dann den Rest im Konstruktor, kehrt zu deinem Konstruktor zurück und erst dann wird zero initialisiert und ist dann erst benutzbar.

Du kannst allerdings vor zero ein static schreiben, damit wird es zu einer Klassenvariable und bei der ersten Verwendung der Klasse initialisiert und damit vor dem Konstruktor und ist so nutzbar.

Ob dass das ist was du willst musst du selber entscheiden.




gebbissimo hat gesagt.:


> Erst hatte ich folgenden Versuch, bekam aber dann die Fehlermeldung "call to this must be first statement in constructor". Muss dies IMMER so sein?



Kurz: Ja!  (Um die Intialisierungsreihenfolge einzuhalten.

Zum weiterlesen: http://www.artima.com/designtechniques/initializationP.html


----------



## gebbissimo (27. Januar 2008)

hi zeja!

Vielen Dank für die ausführliche Antwort, ich habe es mir gerade nochmal durchgelesen und hoffe in etwa verstanden zu haben um was es geht.

Morgen gehts in die Klausur, soll schon klappen 

Danke!


----------



## gebbissimo (27. Januar 2008)

Hallo,

ich habe ein Programm zur Teilerbestimmung von einer Zahl geschrieben, mit instanceof.
Ich habe gelesen es geht auch mit "%" (Rest).

Es müsste prinzipiell doch aber auch mit "instanceof" gehen, oder? Ich erhalte beim if die Fehlermeldung "unexpected type"

Hier mein code:


```
public class WS06_1 {

    public static void teilerliste (int n) {
        double i=1;
        double u;
        
        for (i=1.0; i<=n; i++) {            
            u = n/i;
            if (u instanceof int) {
                System.out.println(u + "ist Teiler von " + n);
            }
        }
    }
        

}
```


----------



## procurve (27. Januar 2008)

Such mal nach "modulo" bei Google, so wie du das gemacht hast, funktioniert es jedenfalls nicht.

instanceOf ist nicht für die Teilerbestimmung gedacht...


----------



## zeja (27. Januar 2008)

instanceof prüft den Typ einer Variablen. In deinem Fall hat u den Typ double. Auch wenn eine Ganzzahl drin stehen würde, würde diese als double ausgedrückt werden, also 1.0 statt 1.

Probiers einfach mit % und nimm ein int für i.


----------



## gebbissimo (27. Januar 2008)

hi!

Die modulo-Weise mit % habe ich hinbekommen, ich dachte es gäbe doch irgendwie eine Möglichkeit dies mit instanceof zu regeln.

Dankeschön!


----------

