Ich möchte eine Subclass von InputStream schreiben, aber ALLE dokumentierten Funktionen von InputStream überschreiben (das hat verschiedene Gründe). Nun habe ich aber ein Problem mit den beiden Read-Funktionen, die byte[] als Übergabe wollen.
Erstens gibt es garkeinen Typ byte[] - zweitens, selbst wenn es einen gäbe: die Funktion benutz Call-By-Reference... Das kann man so nicht nachproggen.
Nein! Es gibt kein Call By Reference in Java. Die Referenzen werden bei der Übergabe immer kopiert. Aber sie zeigen halt aufs gleiche Objekt im Speicher. Also hat es natürlich auch Auswirkungen ausserhalb des Scopes, wenn man dieses Objekt verändert.
Sieh folgender Code:
Code:
public static void fillByteArray(byte[] b) {
byte[] foo = new byte[2];
b = foo;
b[0] = 3;
b[1] = 2;
}
public static void main(String[] args) {
byte[] test = new byte[2];
test[0] = 0;
test[1] = 0;
fillByteArray(test);
System.out.println(test[0] + ", " + test[1]);
}
Nein! Es gibt kein Call By Reference in Java. Die Referenzen werden bei der Übergabe immer kopiert. Aber sie zeigen halt aufs gleiche Objekt im Speicher. Also hat es natürlich auch Auswirkungen ausserhalb des Scopes, wenn man dieses Objekt verändert.
Sieh folgender Code:
Code:
public static void fillByteArray(byte[] b) {
byte[] foo = new byte[2];
b = foo;
b[0] = 3;
b[1] = 2;
}
public static void main(String[] args) {
byte[] test = new byte[2];
test[0] = 0;
test[1] = 0;
fillByteArray(test);
System.out.println(test[0] + ", " + test[1]);
}
Und was hindert einen daran beim Überladen der read(byte[], ...) - Methoden das Erzeugen neuer Referenzen zu unterlassen und mit der bestehenden zu arbeiten?
Hä? Der Zusammenhang dieser Frage ist mir jetzt nicht ganz klar. Ich habe Dir nur versucht zu erklären, dass das, was Du da oben versucht hast zu erklären, kein Call By Reference ist.
Was Du jetzt mit überladen willst, verstehe ich jetzt nicht. Was hat das eine denn mit dem anderen zu tun?
@Threadersteller:
Wenn Du eh alle Methoden überschreiben willst, dann kann es Dir ziemlich egal sein, wie etwaige Methoden in InputStream implementiert sind. Durch das Überschreiben wird dann eh nur Deine Implementierung genutzt.
Hä? Der Zusammenhang dieser Frage ist mir jetzt nicht ganz klar. Ich habe Dir nur versucht zu erklären, dass das, was Du da oben versucht hast zu erklären, kein Call By Reference ist.
Was Du jetzt mit überladen willst, verstehe ich jetzt nicht. Was hat das eine denn mit dem anderen zu tun?
Ich habe nur versucht zu zeigen, dass es a) sehr wohl einen Typ byte[] gibt (wenn es ihn nicht gäbe, dann wäre es ja auch sinnlos, Methoden zu definieren, die einen solchen Typ als Parameter erwarten) und b) wollte ich damit nur zeigen, wie man auf eben diesen Array zugreift, so dass die Daten tatsächlich geändert werden.
Ist doch klar; ab dem Moment, wo du
b = foo
ausführst, stellt b keine Referenz auf die ursprünglichen Daten mehr bereit, sondern die Referenz auf foo. Alle zukünfitgen Zugriffe auf b innerhalb der Methode ändern dann natürlich die neu erzeugte Referenz in foo und nicht mehr die ursprünglich der Funktion übergebene.[/quote]
ausführst, stellt b keine Referenz auf die ursprünglichen Daten mehr bereit, sondern die Referenz auf foo. Alle zukünfitgen Zugriffe auf b innerhalb der Methode ändern dann natürlich die neu erzeugte Referenz in foo und nicht mehr die ursprünglich der Funktion übergebene.
Du nennst Dein Beispiel CallByRef und das ist es eben nicht. Auf nix anderes wollte ich hinweisen. Würde es Call By Reference in Java geben, so würde das b = foo eben auch Auswirkungen auf die Referenz b in der Main Methode haben. Aber aufgrund der Tatsache, dass das b beim Methodenaufruf kopiert wird, ist dem nicht so.
Es gibt kein Call By Reference in Java.
Und dass es den Typ byte[] gibt, steht wohl ausser Frage. Nachzulesen in jedem Java Grundlagenbuch in den ersten Kapiteln. :roll:
ausführst, stellt b keine Referenz auf die ursprünglichen Daten mehr bereit, sondern die Referenz auf foo. Alle zukünfitgen Zugriffe auf b innerhalb der Methode ändern dann natürlich die neu erzeugte Referenz in foo und nicht mehr die ursprünglich der Funktion übergebene.
axo... für solch schnelle Beispiele nehme ich immer nen JavaEditor... der will immer gleich nen Projektnamen wissen und ich hab nur irgendeinen Namen genommen, damit ich mich wieder erinnere, wofür ich das Bsp. angelegt hab
Also ICH persönlich bin da vielleicht jetzt nicht so "wissenschaftlich", aber mir ist im Endeffekt egal, ob das, was ich meine, jetzt Call By Ref ist oder By Value. Wichtig ist mir:
Wenn ich byte[] übergebe (was btw nicht geht WEIL byte KEIN TYP IST MIT DEM JAVA UMGEHEN KANN!!!!!) dann KANN ich nicht das Ergebnis wie oben gesagt in byte[] speichern... Bzw. ich kann es auch nicht in andere Datentypen wie int speichern.
(Das ist btw eine der großen Schwächen von Java)
Und nur DARAUF bezog sich meine Frage... Die Diskussion über ByVal und ByRef wurde ja schon oft genug geführt.
Wenn ich byte[] übergebe (was btw nicht geht WEIL byte KEIN TYP IST MIT DEM JAVA UMGEHEN KANN!!!!!) dann KANN ich nicht das Ergebnis wie oben gesagt in byte[] speichern...
Es gibt kein byte in Java? Herrje, nun müssen alle Bücher umgeschrieben werden. Ich wette da macht Dan Brown wieder ein tolles Buch draus.. "Sakrileg 2" oder so... sicher hat das Erdbeben auf Java auch damit zu tun...
Bzw. ich kann es auch nicht in andere Datentypen wie int speichern. (Das ist btw eine der großen Schwächen von Java)
Wenn es natürlich kein byte gibt, dann kann man es natürlich auch nicht umwandeln, denn bekanntlich nichts von nichts.. Das ist aber mehr ein philosophisches Problem, als ein programmiertechnisches.
Wenn ich byte[] übergebe (was btw nicht geht WEIL byte KEIN TYP IST MIT DEM JAVA UMGEHEN KANN!!!!!) dann KANN ich nicht das Ergebnis wie oben gesagt in byte[] speichern...
Es gibt kein byte in Java? Herrje, nun müssen alle Bücher umgeschrieben werden. Ich wette da macht Dan Brown wieder ein tolles Buch draus.. "Sakrileg 2" oder so... sicher hat das Erdbeben auf Java auch damit zu tun...
Wie UNENDLICH witzig. Du bist garantiert einer von Opus Dei... Ihr wollt DIE WAHRHEIT NICHT SEHEN: ES GIBT KEIN BYTE IN JAVA!!!!!!!
AlArenal hat gesagt.:
Bzw. ich kann es auch nicht in andere Datentypen wie int speichern. (Das ist btw eine der großen Schwächen von Java)[/quote
Wenn es natürlich kein byte gibt, dann kann man es natürlich auch nicht umwandeln, denn bekanntlich nichts von nichts.. Das ist aber mehr ein philosophisches Problem, als ein programmiertechnisches.
Mir würde doch nie einfallen jemanden zu kritisieren, dem nach 11 Jahren Java der grundlegendste aller Konstruktionsfehler der Sprache offenbart wurde, der vorher niemandem aufgefallen ist und alle daran hinderte ordentliche Software in Java zu entwickeln.
Müsste die Sprache nun auf einmal aufhören zu existieren, so wie die Schöpfung wenn man Gottes wahren Namen rückwärts aufsagt?
Wenn du nen Nachschlag möchtest, bitte mich einfach darum; Sarkasmus gibts nämlich heute umsonst....
Ich habe eben noch einen zum Himmel schreienden Fehler gefunden. Ich bekomme es ums verrecken nicht hin JFrame#setContentPane(Container contentPane) mit einem TableModel zu benutzen.
Vielleicht ist des Rätsels Lösung auch in den Wörtern "ich kann" in obigem Zitat zu suchen. Aber was weiß ich schon? Solange mein Chef pünktlich das Gehalt bezahlt, ist doch alles okay....
Ist aber auch kein Konstruktionsfehler, sondern ein Denkfehler bei all denen, die von ihm erwarten, dass der das kann. Die haben offensichtlich keine Ahnung von Hunden. Aber Hauptsache sie wissen wie man "n00b" schreibt....
Fakt 1: Die meisten Hunde können nicht n00b schreiben *sich bewusst verles*
Fakt 2: Ich habe eine Frage gestellt, diese wurde bisher nicht so beantwortet, dass ich was damit anfangen kann, also habe ich meine weiteren Probleme geschildert. Das obige Beispiel funktioniert so nicht, und auch nicht, wenn ich es mit int[] mache.
Fakt 3: Sollte niemand eine Antwort haben, dann werde ich halt leider selber schauen müssen, wie ich weiterkomme. Aber dann lass wenigstens das Gespamme. Ich habe FREUNDLICH gefragt, aber wenn man mir so kommt...
Vielleicht ist es dir nicht aufgefallen, aber keiner versteht wo zur Hölle eigentlich dein Problem liegt. Ein byte ist ein byte ist ein byte. Es ist, entgegen deiner Behauptung, existent und benutzbar. Wie du siehst kann ich sehrwohl lesen, aber entweder hast du zuvor noch nicht genug gelesen, oder aber bist nicht willens oder in der Lage dein Problem ordentlich zu beschreiben.
Naürlich gibt es nicht für jeden Zweck bereits ne fertige Klasse, soweit warst du ja schon selbst. Eine Analogie zu deinem Eingangspost wäre "Ich will ein Auto bauen. Es soll genau wie mein BMW 320i aussehen und funktionieren. Man soll keinen Unterschied bemerken. Ich will es aber sowohl mit Wasserstoff, als auch mit Benzin und zur Not mit der Steckdose tanken.".
Die Logik sagt einem, dass das nicht geht. Ebenso sagt die Logik (bzw. die Spezifikation der Sprache), dass man einer Methode die byte[] erwartet auch nur byte[] übergeben kann. Da kannst du nun einen auf Rumpelstielzchen machen, oder aber überlegen, wie du es anders umsetzt.
Ehrlich gesagt wüsste ich in diesem Beispiel auch nicht wo der Sinn darin liegen soll was anderes reinzuschieben, als die Methode erwartet. Wenn ich (als Klasse/Methode) ein Steak bestelle, will ich auch nicht stattdessen Spinat bekommen. Es würde aber auch keiner ungefragt einfach stattdessen Spinat servieren.
Warum also zum Teufel soll das Ding vorgeben was zu sein, was es nicht ist? Wer oder was stellt so dämliche Anforderungen?
Wenn ich byte[] übergebe (was btw nicht geht WEIL byte KEIN TYP IST MIT DEM JAVA UMGEHEN KANN!!!!!) dann KANN ich nicht das Ergebnis wie oben gesagt in byte[] speichern... Bzw. ich kann es auch nicht in andere Datentypen wie int speichern.
Entweder wissen wir alle nicht, worauf du hinaus möchtest oder Deine Behauptung ist schlichtweg falsch. byte ist sehrwohl ein Datentyp, mit dem Java umgehen kann; er gehört sogar zu den primitven Datentypen (wie auch int, long, ...)
A primitive type is predefined by the Java programming language and named by its reserved keyword (§3.9):
...
IntegralType: one of
byte short int long char
Nach Deiner Theorie kann Java damit nicht umgehen; das hiesse read(byte[] bvar) wäre eine Methode, die nie korrekt aufgerufen werden kann; wieso sollte jemand Methoden deklarieren und in die Java API aufnehmen, die nicht aufgerufen werden können? Diese würden nichtmal compiliert werden können, wenn Java byte nicht handhaben können würde.
Um mich nun nochmal an das Problem zu machen, wie ich es verstanden habe:
Du willst die Methoden read(byte[], ...) überladen und glaubst Probleme zu haben, weil diese Methoden in einen Array schreiben sollen, der als Parameter übergeben wurde. Das sollte aber eigentlich keine Probleme machen, wenn man sich anschaut, wie die Methoden in der API erklärt sind. Diese read Methoden gehen alle von der Existenz der byte[] Variable aus (in diesem Fall meine ich mit Existenz Variable != null ). Des weiteren wird ein übergebener Array auch nur in den Indizierungsgrenzen benutzt, wie er deklariert wurde; sprich ein byte[] Array mit einer Größe 10 wird auch nur mit max. 10 Werten belegt. Das heisst auch diese read Methoden vermeiden das Anlegen neuer Referenzen, so dass auch wirklich der übergebene Array geändert wird (siehe vorherige Diskussion ^^). Unter berücksichtigung dieser Dinge sollte es kein Problem sein, entsprechende Methoden selbst zu implentieren
Code:
class FooBar extends InputStream
{
public int read(byte[] b) throws ...
{
if (b == null)
throw new NullPointerException();
// aus dem Stream lesen und die Anzahl gelesener Bytes zurückgeben
// z.B.
long bytesRead = 0;
//* if (streamIsAtEnd)
return -1;
for (long i=0;i<b.length;i++)
{
//* if (!streamIsAtEnd)
{
//* b[i] = gelesenes Byte
bytesRead++;
}
}
return bytesRead;
}
}
Diese Methode sollte in etwa das tun, was die "echte" read - Methode auch tut (zumindest vom Grundverhalten her).
Zeilen beginnend mit "//*" sind symbolisch gemeint und müssen entsprechend implementiert werden. Ebenso fehlt das werfen der IOException an gegebener Stelle.
Als Skizze, wie das realisierbar ist, sollte das aber genügen.
Das ganze Funktioniert, weil byte[] im Gegensatz zu byte kein primitiver Datentyp, sondern ein Array ist. D.h. man kann tatsächlich mit der Methode die Werde im Array verändern.
Diese Methode würde also tatsächlich den Wert der Variable b ausserhalb der Methode nicht ändern können:
Code:
public void changePrimitiveByte(byte b)
{
b++;
}
Diese Methode jedoch schon, da sie genau mit der Referenz auf den übergebenen Array auf die selben Werte im Speicher zugreift:
Code:
public void changeByteArray(byte[] b)
{
for (int i=0;i<b.length;i++)
b[i]++;
}
Wenn das Deine Frage nicht beantwortet, dann helfe uns, Dein Problem zu verstehen.
Ach. Ist egal. Ich werds schon irgendwie rausfinden.
Das Problem ist, dass genau dein Beispiel nicht geht, weil javac meckert, dass er nicht weiß, was byte ist.
Das Andere war, dass ich - nur so zum "test" - mal was vergleichbares mit int[] geschrieben habe - das auch nicht ging, woraus ich schloss, dass das int-Array nicht als Referenz übergeben wurde, woraus ich wiederum schloss, dass man, selbst wenn es bytes gibt, diese nicht als reine referenz übergeben kann.
Mir jetzt egal. Bis ich da noch ne große weitere Diskussion anzettle, mach ichs halt gleich anders und schreibe KEINE Subklasse von InputStream.
Ach. Ist egal. Ich werds schon irgendwie rausfinden.
Das Problem ist, dass genau dein Beispiel nicht geht, weil javac meckert, dass er nicht weiß, was byte ist.
Das Andere war, dass ich - nur so zum "test" - mal was vergleichbares mit int[] geschrieben habe - das auch nicht ging, woraus ich schloss, dass das int-Array nicht als Referenz übergeben wurde, woraus ich wiederum schloss, dass man, selbst wenn es bytes gibt, diese nicht als reine referenz übergeben kann.
Mir jetzt egal. Bis ich da noch ne große weitere Diskussion anzettle, mach ichs halt gleich anders und schreibe KEINE Subklasse von InputStream.
hmm normaler Weise sollte javac sich nicht über byte's beschweren. Es sei denn, die Java-Installation ist irgendwie verhunst oder es wurde tatsächlich ein Fehler beim Programmieren begangen. In diesem Fall wäre die genaue Fehlermeldung sowie ein Codeschnipsel, wo das Problem aufgetreten ist, ganz nützlich.
Es geht uns auch nicht darum, Diskussionen anzuzetteln. Die Schwierigkeit mit
dir war ausschließlich daß du so penetrant behauptetest, daß es in Java kein Byte
gibt.
Schoppenhauer hat gesagt.:
dass genau dein Beispiel nicht geht, weil javac meckert, dass er nicht weiß, was byte ist
Ich hab keinen Bock mehr zu diskutieren und mich beleidigen zu lassen. Drum hab ich mein Häkchen druntergesetzt. Ich mach es jetzt einfach anders, und gut is.
Trotzdem Danke.
Wenn er nicht Willens ist, mal in Betracht zu ziehen, dass er eventuell einen Fehler gemacht hat, kann er sich gerne in einem anderen Forum umsehen, denn dann können wir ihm hier auch nicht mehr helfen.
Wenn er nicht Willens ist, mal in Betracht zu ziehen, dass er eventuell einen Fehler gemacht hat, kann er sich gerne in einem anderen Forum umsehen, denn dann können wir ihm hier auch nicht mehr helfen.
Wobei du dann die dritte Seite warst
Durch deine letzten, rein auf die eigentliche Fragestellung bezogenen, Posts
hast du ja immerhin versucht, ihn wieder ins Boot zu holen; was jedoch
nicht gewürdigt wurde:
Schmollihauer hat gesagt.:
Ich hab keinen Bock mehr zu diskutieren und mich beleidigen zu lassen.