Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
beim Kompilieren kommt ne Fehlermeldung wenn ich später nen Aufruf wie
Java:
double result = v(3,4,'z');
mache. Sie lautet: "Reference to v is ambiguous, both method...match"
Kern der Aussage, soweit ich das verstehe. Es "passen" beide Methoden. Die Signaturen sind doch aber unterschiedlich. Warum geht das überladen so nicht? Im ersten fall ist meine Signatur: v(int,int,int). Im zweiten: v(double,double,char). Insbesondere der letzte Parameter, das char, ist ja wohl deutlich vom int zu unterscheiden. Bei dem anderen geh ich mal von aus das die Parameter von int in double konvertiert werden könnten.
Wo liegt also der Fehler?
Java:
public static int v(int r, int h, int k) {
return r+h+k;
}
public static double v(double r, double h, char typ) {
return r+h+k;
}
Stell die folgende Frage:
Welcher Parameter hat höhere Priorität beim widening?
Das kann und darf die JVM nicht entscheiden also gibt es den ambigious Fehler.
char -> short ist kein widening, sondern narrowing, da char 16bit, short zwar ebenfalls 16bit aber zweier Komplement. Du must casten und verlierst möglicherweise etwas.
Sehe ich es richtig das widening: typ in anderen "genauerer" typ umwandeln. wie int zu double. shortening ist umgedreht. also typgenauigkeit bzw. wertebereich eingschränken, z.B. double zu int?
Warum ein char als int dargestellt werden kann ist mir aber noch unklar.
Aber der compiler weiß halt nicht ob er die übergeben parameter "erweitern" soll zu double oder halt als int interpretieren soll, richtig?
Die JVM würde später Probleme haben zu entscheiden, welcher Methodenaufruf geschehen soll, weil in beiden Fällen aus deinem Beispiel, der Datentyp erweitert (widening) werden muss.
Wenn die Datentypen exakt für den Aufruf passen, hat der Compiler auch keine Probleme.
shortening gibt es nicht, dies geht nur durch explizites casten mit möglichem Verlust von Daten.
Das ist eine Konvention in Java und liegt daran: Char ist 16bit lang, unsigned, also 0 bis 65535. Byte kann den char nicht fassen (weil 8bit signed), short auch nicht (16bit aber signed). Bleibt als kleinster Datentyp nur noch int übrig (32bit, signed). Jeder char ist ein einzelnes 16bit Unicode-Zeichen '\u0000' bis '\uffff', das intern als Zahl dargestellt wird (int).
Ersetze die 3 und durch die vier durch 3.0 und 4.0, dann meckert er nicht mehr.
Grundsätzlich gilt: Zahlenliterale ohne Dezimalpunkt werden als Integer gedeutet, solche mit Dezimalpunkt als Doubles.
Ein char ist kein int; char ist 16 Bit, int ist 32 Bit groß. Ein char wird als Unicode-Zeichen interpretiert, ein int als eine Zahl im Zweierkomplement.
Allerdings paßt ein char problemlos in ein int. Wenn Du Deine Methode aufrufst, muß irgendwo konvertiert werden, entweder die beiden ints in double oder das char in int.
Noch eine kleine Anmerkung: Irgendwo weiter oben wurde gesagt, daß ein char ein Unicode-Zeichen enthalte. Das stimmt nicht mehr, sobald beispielsweise 32-Bit-Zeichenadressen wie bei UTF-32 verwendet werden, was dann bei Java hübsche Probleme bereiten kann.
ich hab es so verstanden. Intern ist ja sowieso jeder Datentyp einfach nur ein Bitmuster. Was ich davor schreibe int, double oder char sagt mir ja quasi nur, wie ich das Bitmuster zu interpretieren habe.
Ich find es nur blöd das ein char (intern ein Bitmuster von einer Länge mit 2 Byte) nun automatisch in ein int umgewandelt werden kann (widening conversion). Denn Sinn und Zweck ist es ja Zeichen darzustellen und nicht diese Zeichen in eine Zahl umzuwandeln.
Ich hab zwar verstanden das halt diese automatische Konvertierung möglich ist, aber der Sinn wieso ist mir noch nicht erschlossen.
Auf der Festplatte befinden sich Bits, und die müssen halt je nach dem entweder als Zeichen oder als Zahlen "gedeutet" werden, insofern ist es schon sinnvoll, dass man beides ineinander umwandeln kann. Ein InputStreamReader hat z.B. eine read()-Methode, die ein int liefert - egal ab es gerade DLLs oder Shakespeares gesammelte Werke liest, aber diesen int kannst du eben ganz leicht in einen char umwandeln (nicht dass ich einen InputStreamReader für Shakespeares gesammelte Werke empfehlen würde, da gibt es bessere Varianten wie BufferedReader oder ClassicalLiteratureReader).
Das char ein 32bit Zeichen halten könnte ist interessant. Bisher habe ich nur gehört, das man im JSR-204 ein char32 einführen wollte, der das kann, das kam aber nicht so, stattdessen konnte der String Teile wie \U20000 halten. Diese Zeichen sollten aber auch in zwei chars gespeichert werden.
So ist mein Stand zu Java 6, bei 7 weis ich nicht.
Java:
char c0 = '\u4444';
char c1 = '\u20000'; // geht nicht
char32 c2 = '\u20000'; // gibs nicht
String c3 = "\u20000";
System.out.println("length" + c3.length()); // = 2
Das heißt, jedes Land dieser Erde könnte 273 Schriftzeichen für sich benutzen. Davon muss man noch mal 500 Sonderzeichen und ca. 3000 chinesische Schriftzeichen abziehen, sowie 52 lateinische Buchstaben:
(2^16 - 500 - 3000 - 52) / 240 = 258
Also immernoch viel zu viele...
Hat also jemand einen triftigen Grund, sowas zu benutzen??