Anfänger steht auf dem Schlauch

  • Antworten:10
  • Bentwortet
Johannes Sonnentag
  • Forum-Beiträge: 13

19.02.2010, 18:06:33 via Website

Hi ich bin gerade dabei meine erste app zu schreiben.

Und wenn ich dort eine Funktion schreibe z.b:

1long posx(Canvas c)
2{
3 if (mTouchX >=0 && mTouchY >= 0)
4 {
5 long pos = SystemClock.elapsedRealtime();
6 }
7 return pos;
8}

Dann kann ich die Variable pos ja nicht zurückgeben, weil die ja nur in ihrem Block gültig ist.

Ich habe mir schon viel zu viel darüber den Kopf darüber zerbrochen und bin trotzdem nicht drauf gekommen. :(

Ist bestimmt das billigste was es gibt^^.

Gruß
Hannes

Antworten
Jack-In-Da-Box
  • Forum-Beiträge: 1.569

19.02.2010, 18:16:46 via Website

einfach GLOBAL deklarieren...

Beispiel:
1public class Main extends Activity {
2
3 String str_test;
4
5 @Override
6 public void onCreate(Bundle savedInstanceState) {
7
8 super.onCreate(savedInstanceState);
9 setContentView(R.layout.main);
10
11 str_test = "wert";
12
13 }
14
15}

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

19.02.2010, 18:28:40 via Website

Wie wäre es ein -1L zurückzuliefern wenn die Bedingung nicht greift, anstatt alles global zu halten ?

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Johannes Sonnentag
  • Forum-Beiträge: 13

19.02.2010, 18:43:52 via Website

Ach ich habe vergessen zu erwähnen, dass das ganze ein Live Wallpaper werden soll und die Funktion den Wert zurück liefern soll, wenn ein Touch erfolgt ist.

Ich habe das ganze vom vorhandenen Beispiel abgeleitet.

Unten kommt man in die Ordnerstruktur.

Antworten
Matthias La Schmu
  • Forum-Beiträge: 158

19.02.2010, 19:15:24 via Website

Johannes Sonnentag
1long posx(Canvas c)
2{
3 if (mTouchX >=0 && mTouchY >= 0)
4 {
5 long pos = SystemClock.elapsedRealtime();
6 }
7 return pos;
8}
Dann kann ich die Variable pos ja nicht zurückgeben, weil die ja nur in ihrem Block gültig ist.

Funktionsintern zur Verfügung stellen, nicht If-Intern.

1long posx(Canvas c)
2{
3 long pos = -1;
4 if (mTouchX >=0 && mTouchY >= 0)
5 {
6 pos = SystemClock.elapsedRealtime();
7 }
8 return pos;
9}

lg, La Schmu.

Antworten
Johannes Sonnentag
  • Forum-Beiträge: 13

19.02.2010, 19:40:33 via Website

Juhu es funzt.

Aber wenn ich mit der Zeit etwas ausrechnen möchte, kommt ja voll der Müll raus, wenn die zeit -1 ist, oder wird das irgendwie abgefangen.

Mich würde trotzdem noch interessieren, wie man aus dem posx eine Globale Variable macht, denn die Klasse R ist ja dort nicht vorhanden.

Aber wie kommt jetzt der Wert pos aus dem Block heraus?
Die Gültichkeit ist doch auf die If schleife begrenzt.

— geändert am 19.02.2010, 19:46:14

Antworten
Johannes Sonnentag
  • Forum-Beiträge: 13

19.02.2010, 22:52:24 via Website

So ich hab das ganze jetzt mit static gelöst, so war die variable erstellt und ich konnte sie immer und überall ändern und es Funzt :grin:

Antworten
Matthias La Schmu
  • Forum-Beiträge: 158

19.02.2010, 22:57:49 via Website

Johannes Sonnentag
Aber wenn ich mit der Zeit etwas ausrechnen möchte, kommt ja voll der Müll raus, wenn die zeit -1 ist, oder wird das irgendwie abgefangen.
Das musst du generell nochmal abfangen
Bsp:
1long pos = posx(canv);
2if(pos != -1)
3{
4 /...
5}

Johannes Sonnentag
Mich würde trotzdem noch interessieren, wie man aus dem posx eine Globale Variable macht, denn die Klasse R ist ja dort nicht vorhanden.
"Globale" - Variablen gibt es so in Java nicht. Lediglich Klassenattribute/Constants.

Johannes Sonnentag
Aber wie kommt jetzt der Wert pos aus dem Block heraus?
Die Gültichkeit ist doch auf die If schleife begrenzt.
Alle Variablen in einem IF-Block sollten/sind nur in einem IF-Block gültig (sein). Jedoch kann ich in einem If-Block auf Funktionsvariablen zugreifen. Da ich die Variable vor dem Block deklariere und sie nur im Block befülle, ist sie damit auch außerhalb des If-Blocks gültig.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

20.02.2010, 08:38:35 via Website

So ich hab das ganze jetzt mit static gelöst, so war die variable erstellt und ich konnte sie immer und überall ändern und es Funzt

Warte ab, du wirst bald merken das so etwas zum einen mehr Nachteile als Vorteile bringt, zum anderen ist Java eine Objektorientierte Sprache, mit Prozeduraler Programmierung kommt man irgendwann in Probleme. Ich will hier nicht das schlüsselwort static verteufeln, allerdings bin ich der Ansicht das static in 99% der fälle nur mit dem Schlüsselwort final benutzt werden sollte. Dann hast du auch eine "globale variable", kannst diese aber nicht mehr verändern, der Compiler freut sich ebenfalls. Interessant wird das ganze mit static wenn du Threads benutzt, dann wird teilweise hässlich!

So genug dazu. Wie hier schon angedeutet wurde, du solltest den Gültigkeitsbereich von Variablen möglichst klein halten, nur so wirst du den Überblick behalten.
Eine Methode wie diese hier kann man deutlich aussagekräftiger Schreiben (Bei Java spricht man allgemein von Methoden statt Funktionen):



1long posx(Canvas c)
2{
3 long pos = -1;
4 if (mTouchX >=0 && mTouchY >= 0)
5 {
6 pos = SystemClock.elapsedRealtime();
7 }
8 return pos;
9}

Das ist zwar nett, besser wäre folgendes, und dann sind wir bei static final Deklarationen:

1private final static long NO_RESULT_VALUE = -1L;
2....
3long posx(Canvas c)
4{
5 long pos = NO_RESULT_VALUE;
6 if (mTouchX >=0 && mTouchY >= 0)
7 {
8 pos = SystemClock.elapsedRealtime();
9 }
10 return pos;
11}

Hierdurch lässt sich auch Code der damit weiterarbeiten muss lesbarer machen:

1long pos = posx(canv);
2if(pos != NO_RESULT_VALUE)
3{
4
5}

Programmieren ist vor allem Disziplin. Gewöhne dir sie an, und du wirst in einigen Wochen/Monaten deinen eigenen Code selbst schneller und besser verstehen obwohl du zwischendurch andere Dinge getan hast.

NO_RESULT_VALUE kann jetzt z.b mittels Eclipse/Netbeans Refactorings unbenant werden, dabei muss man nicht das Projekt durchsuchen und alle -1L Werte heraussuchen, was mehr als Fehleranfällig ist, stattdessen kannst du .b den Namen oder den Wert verändern, letzteres geschieht exakt an einer stelle.

hth,
Mac

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Johannes Sonnentag
  • Forum-Beiträge: 13

22.02.2010, 23:32:13 via Website

So Mac erst mal danke für deinen aufschlussreichen Beitrag.
Aber eins verstehe ich noch nicht was bedeutet der Wert -1L?

1private final static long NO_RESULT_VALUE = -1L;
2....
3long posx(Canvas c)
4{
5 long pos = NO_RESULT_VALUE;
6 if (mTouchX >=0 && mTouchY >= 0)
7 {
8 pos = SystemClock.elapsedRealtime();
9 }
10 return pos;
11}

Mac[/quote]

So und dann noch was.
Man muss wissen, dass ich aus der PHP Abteilung komme.
Da ist das so, dass wenn ich dort einen Array erstellen wollte, dann hab ich einfach
1array = array("hallo","ball")
geschrieben und es hat funktioniert, aber hier ist das irgendwie anderst.
Hier muss man irgendwas mit new ...
ich hab schon auf einigen Seiten geschaut, aber da stehen manchmal ganz verschiedene Dinge und dann hab ich keine Ahnung was da jetzt stimmt.

Jetzt sollte ich halt mal wissen wie man einen ganz schlichten Array erstellt. Und ob oder wie man die Größe angibt (muss).

Gruß
Hannes

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

23.02.2010, 09:35:38 via Website

Das -1L sagt aus du du einen LONG wert hast, das ist deutlich konkreter als -1. Auch wenn es im Kontext hier überflüssig erscheinen mag.
Du drückst dich auch hier genauer aus. Bei Mathematischen Berechnungen kann es sonst sein das der Compiler statt long nur den int benutzt und du somit falsche Ergebnisse bekommst. (Ich kann das gerade nicht konkreter darstellen).

PHP hat assoziative Arrays, das sind in Java z.b HashMap bzw. HashTable und einer reihe weiterer.

1HashMap map = new HashMap();

Besser ist sowas:

1Map map = new HashMap();

Hier ist map das Interface, da z.b HashMap und HashTable beide das Interface Implementieren hast du die Möglichkeit später noch zu wechseln.
Jetzt fragst du dich vielleicht wieso sollte man etwas wechseln, nun dafür mag es vielerlei Gründe geben. Einer wäre z.b das du ein SortedMap haben willst.
Die Javadoc erklärt das schon ganz gut:
A map that further guarantees that it will be in ascending key order, sorted according to the natural ordering of its keys (see the Comparable interface), or by a comparator provided at sorted map creation time
.

SortedMap ist auch nur eine Map! Also um hier nicht komplett abzuschweifen, es ist meist besser gegen ein Interface zu Programmieren als gegen eine konkrete Klasse wie HashMap.

Und noch etwas, was den Code deutlich lesbarer macht, was in PHP so meine Ich nicht existiert da PHP Dynamische Typen hat (nennt man das so ?)

1Map<String,String> map = new HashMap<String,String>();


In den <> stehen die Typen für des Key bzw Value. Damit ersparst du dir das was bei PHP eher nicht vorkommt, das casten. Ein cast ist sowas:

1EinTyp typ = (EinTyp) map.get(Schlüssel);


Mittels Nutzung der Generics, ist das überflüssig, lege einfach fest was in der Map enthalten sein soll:

1Map<String,EinTyp> map = new HashMap<String,EinTyp>();
2...
3EinTyp typ = map.get(Schlüssel);

Der Compiler prüft so etwas vor dem Kompilieren, daher bist du auf der sicheren Seite. Du kannst auch nicht falsche Objekt-Typen in eine Map stecken!

hth,
Mac

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten