# java.io.InputStream.read(byte[] b) überschreiben



## schoppenhauer_entfernt_ (2. Jun 2006)

Hallo.

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.

Aber wie macht man es dann?

Wäre sehr gut, wenn mir das jemand sagen könnte.


----------



## moormaster (2. Jun 2006)

Wieso soll das nicht gehen? Das funktioniert doch prima:


```
class FooBar
{
	public static void fillByteArray(byte[] b)
	{
		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]);
	}
}
```

das liefert die Ausgabe:
3, 2


----------



## byte (3. Jun 2006)

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:


```
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]);
	}
```


----------



## moormaster (3. Jun 2006)

byto hat gesagt.:
			
		

> 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:
> 
> ...



Und was hindert einen daran beim Überladen der read(byte[], ...) - Methoden das Erzeugen neuer Referenzen zu unterlassen und mit der bestehenden zu arbeiten?


----------



## byte (3. Jun 2006)

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.


----------



## moormaster (3. Jun 2006)

byto hat gesagt.:
			
		

> 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]


----------



## byte (3. Jun 2006)

moormaster hat gesagt.:
			
		

> 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.




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:


----------



## moormaster (3. Jun 2006)

byto hat gesagt.:
			
		

> moormaster hat gesagt.:
> 
> 
> 
> ...



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


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

WTF???

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.


----------



## AlArenal (3. Jun 2006)

Schoppenhauer hat gesagt.:
			
		

> 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.


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

AlArenal hat gesagt.:
			
		

> Schoppenhauer hat gesagt.:
> 
> 
> 
> ...


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.


n00b! ich SAGTE: ich kann selbige Konstruktion NICHT EINMAL MIT ANDEREN DATENTYPEN wie int, double, etc., durchführen...
*Übe Lesen!*


----------



## AlArenal (3. Jun 2006)

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....


----------



## AlArenal (3. Jun 2006)

P.S.:



			
				Schoeppenhauer hat gesagt.:
			
		

> ich SAGTE: ich kann selbige Konstruktion NICHT EINMAL MIT ANDEREN DATENTYPEN wie int, double, etc., durchführen...



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....


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

Fakt: Es geht nicht.


----------



## AlArenal (3. Jun 2006)

Schoppenhauer hat gesagt.:
			
		

> Fakt: Es geht nicht.



Fakt: Mein Hund kackt keine Salami. 

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....


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

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...


----------



## AlArenal (3. Jun 2006)

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?

Und wer zur Hölle ist hier eigentlich der noob?


----------



## AlArenal (3. Jun 2006)

P.S.:
Mach hinne, mein Fluchkonto kommt bald in den roten Bereich...


----------



## Leroy42 (3. Jun 2006)

Ich mische mich mal rein aus Neugierde ein, und verzichte ausnahmsweise
mal auf Sarkasmus (fällt mir wirklich nicht leicht)



			
				Schoppenhauer hat gesagt.:
			
		

> Ihr wollt DIE WAHRHEIT NICHT SEHEN: ES GIBT KEIN BYTE  IN JAVA!!!!!!!



Dann erklär uns deine Definition von "es gibt". Oder anders gefragt, 
wo sind denn Unterschiede in der Behandlung von byte und int in Java.

Das es den Datentyp int _gibt_, erkennst du ja an.


----------



## byte (3. Jun 2006)

Schoppenhauer hat gesagt.:
			
		

> Die Diskussion über ByVal und ByRef wurde ja schon oft genug geführt.



Offenbar noch nicht oft genug...



			
				Schoppenhauer hat gesagt.:
			
		

> Erstens gibt es garkeinen Typ byte[]



byte = primitiver Datentyp zur Darstellung der Zahlen von -2^7 bis 2^7-1
byte[] = Array von bytes

Nachzulesen in JEDEM Java-Buch, das Grundlagen behandelt (wie ich oben bereits sagte).


----------



## moormaster (3. Jun 2006)

Schoppenhauer hat gesagt.:
			
		

> 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, ...)

nachzulesen in der Java Language Specification: http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#85587



> 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.


----------



## moormaster (3. Jun 2006)

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


```
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:

```
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:

```
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.


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

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.


----------



## moormaster (3. Jun 2006)

Schoppenhauer hat gesagt.:
			
		

> 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.


----------



## Leroy42 (3. Jun 2006)

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



Das wird der Compiler mit Sicherheit nicht geschrieben haben. Ein korrektes
Zitat der Fehlermeldung wäre hilfreicher.

Aber egal, wenn dus jetzt anders machst.

Vergiß aber nicht das Licht auszumachen (Häkchen setzen)


----------



## schoppenhauer_entfernt_ (3. Jun 2006)

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.


----------



## AlArenal (5. Jun 2006)

Schade.. ich komme gerade ausm Wochenende und dachte ich würde hier etwas mehr Amusement finden.


----------



## moormaster (5. Jun 2006)

AlArenal hat gesagt.:
			
		

> Schade.. ich komme gerade ausm Wochenende und dachte ich würde hier etwas mehr Amusement finden.



Wenn der Fragende in keinster Weise mehr ernst genommen wird, dann braucht man sich auch nicht zu wundern, dass eben dieser woandershin verschwindet.


----------



## L-ectron-X (5. Jun 2006)

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.


----------



## moormaster (5. Jun 2006)

L-ectron-X hat gesagt.:
			
		

> 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.



Sagen wir es so: Es haben beide Seiten etwas übertrieben.


----------



## thE_29 (6. Jun 2006)

War die Frage eigentlich ernst gemeint?


----------



## Leroy42 (6. Jun 2006)

moormaster hat gesagt.:
			
		

> Sagen wir es so: Es haben beide Seiten etwas übertrieben.


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.


Frühestens jetzt _könnte_ man von Beleidigung sprechen, darum.


			
				Leroy hat gesagt.:
			
		

> Hiermit distanziere ich mich von einem Teil dieses Posts!


----------



## AlArenal (6. Jun 2006)

Jungens, nun wirds aber anstrengend


----------



## moormaster (6. Jun 2006)

AlArenal hat gesagt.:
			
		

> Jungens, nun wirds aber anstrengend



In einer Sache hat er recht gehabt: Es macht keinen Sinn weiter darüber zu diskutieren; abgesehen davon, dass es schon längst offtopic ist ^^


----------

