Methoden Unerwarteter Methodenaufruf

  • Themenstarter Themenstarter Spacerat
  • Beginndatum Beginndatum
S

Spacerat

Gast
Hallo...
Ich hab' jetzt 'ne Sorge, mit der ich nicht unbedingt klar komme. Und zwar habe ich mir bei BufferedImage, ColorModel, SampleModel usw. folgende Sache abgeschaut und relativ oft verwendet:
Java:
Object getData(Object transferContainer)
{
  if(transferContainer == null) {
    transferContainer = new int[3];
  }
  if(transferContainer instanceof byte[]) {
    // fill object with bytes...
  } else if(transferContainer instanceof int[]) {
    // fill object with ints...
  } else {
    // tell user, that transferContainer isn't supported
  }
  return transferContainer.
}
oder
Java:
void setData(Object transferContainer)
{
  if(transferContainer == null) {
    throw new NullPointerException();
  }
  if(transferContainer instanceof byte[]) {
    // copy data from bytes...
  } else if(transferContainer instanceof int[]) {
    // copy data from ints...
  } else {
    // tell user, that transferContainer isn't supported
  }
}
Das ist 'ne Art Object-ReUse mit unbestimmten Datentypen und funktioniert auch unheimlich gut (mit Buffern, primitiven Arrays und Wrapperarrays). Nun aber erweist sich in Klassen, wo man so etwas verwendet eine Kleinigkeit als äusserst fatal. Im Beispiel verwende ich ein int Array mit 3 Elementen. Wenn ich jetzt einen einzigen Integer 3 mal übergeben will, dachte ich mir, das könnte man so machen:
Java:
void setData(int singleInt)
{
  setData(new int[] {singleInt, singleInt, singleInt});
}
Aber genau da habe ich mich verzockt. Wenn ich diese Methode aufrufen will (in Eclipse wird diese auch als Verweis angezeigt) boxed die JVM den "singleInt" in Integer-Wrapper und ruft die Object-Implementierung sofort auf, aber warum macht sie das?
 
Zuletzt bearbeitet von einem Moderator:
So direkt macht er das erstmal nicht
Java:
public class ArgTypeTest
{
	public static void main(String[] args)
	{
		setData(123);
	}
	
	static void setData(int singleInt)
	{
		System.out.println("Single: "+singleInt);
		setData(new int[] {singleInt, singleInt, singleInt});
	}
	
	static void setData(Object data)
	{
		System.out.println("Object: "+data);
	}
}

Warum er es DOCH macht kann verschiedene Ursachen haben: Der singleInt wird schon als Integer (d.h. object) übergeben, oder der Aufruf passiert über ein Interface, wo die 'int'-Methode nicht bekannt ist... oder irgendwas anderes, was man sich aus Chapter 15. Expressions herleiten kann 😉
 
Spacerat hat gesagt.:
Aber genau da habe ich mich verzockt. Wenn ich diese Methode aufrufen will (in Eclipse wird diese auch als Verweis angezeigt) boxed die JVM den "singleInt" in Integer-Wrapper und ruft die Object-Implementierung sofort auf, aber warum macht sie das?
Also, dass er in die Object-Implementierung (setData(Object data))geht, ist klar. Du erzeugst einen Array und ein Array ist ein Object. Ich glaube auch nicht, dass er da irgendwas boxed. Wie kommst Du darauf?
 
@nillehammer: Klar, so sollte es sein. Er sollte in die "singleInt"-Methode springen, ein Array-Objekt erstellen und dann die Objekt-Methode aufrufen, so hätte ich es auch erwartet. ???:L
Nun, er hat's geboxed... Das war für mich auch nicht Nachvollziehbar. Eclipse zeigt den erwarteten Methodenaufruf an, ohne gemecker über "ambiguous" oder so, aber beim Debuggen boxed er plötzlich und es fliegt 'ne Exception. Keine Ahnung warum. Wenn ich Marcos Beispiel ausführe, boxed er auch nicht. Real findet der Aufruf in einer anderen Klasse statt und die Methoden haben einen generischen RückgabeTyp. Sie heissen auch nicht "setData" oder verwenden ints sondern "div" und verwenden doubles. Aber daran kann's doch wohl nicht liegen.
 
Ich würde erst mal testweise die [c]setData(int)[/c]-Methode umbenennen, und schauen was dann rauskommt...

An Marcos Anmerkung könnte was dran sein: Vielleicht versuchst du sowas wie ein multiple dispatch, was Java bekanntlich nicht kann.
 
Wow... das Testweise Umbenennen brachte zwar zunächst nur einen Fehler aber nach einem Project->clean war dann alles ok. Danach der Test und die Methode erneut in das was es sein sollte umbenannt und schon läuft alles wie erwartet. Fazit wäre dann wohl, dass ein simpler Rebuild manchmal echt Wunder wirkt, vor allem dann, wenn unvorhergesehenes passiert.
 

Neue Themen


Zurück
Oben