2013-07-15 3 views
11

Ich habe heute einen Bug aufgespürt, und ich bemerkte etwas Seltsames in einer unserer Klassen. Ich schneide so viel Code wie möglich heraus hier posten:Wie unterscheidet Java diese verschiedenen Methoden mit demselben Namen/derselben Signatur?

class A { 
    static int obtainNumber() { return 42; } 
    static int obtainNumber() { return 3; } 
    static int obtainNumber() { return -1; } 
    static { 
     System.out.println(obtainNumber()); 
    } 
} 

Diese Klasse hat drei Methoden mit exakt den gleichen Namen und Unterschrift. Zuerst dachte ich, das wäre ein ungültiger Code, aber dann hätte Eclipse den Code rot markiert. Es funktioniert:

Also dachte ich vielleicht Java wird nur die erste, die es sieht, verwenden. I neu geordnet Test:

class A { 
    static int obtainNumber() { return 3; } 
    static int obtainNumber() { return -1; } 
    static int obtainNumber() { return 42; } 
    static { 
     System.out.println(obtainNumber()); 
    } 
} 

Nö, das gleiche Resultat:

javac A.java && java A 
42 
Exception in thread "main" java.lang.NoSuchMethodError: main 

Ich dachte, vielleicht nutzt es den mit 42, weil seine größten. Um dies zu testen, nahm ich das Original und verändert die Rückgabewerte:

class A { 
    static int obtainNumber() { return 0; } 
    static int obtainNumber() { return 1; } 
    static int obtainNumber() { return 2; } 
    static { 
     System.out.println(obtainNumber()); 
    } 
} 

Es weiß noch die erste zu verwenden:

javac A.java && java A 
0 
Exception in thread "main" java.lang.NoSuchMethodError: main 

Und wenn ich sie neu ordnen wieder:

class A { 
    static int obtainNumber() { return 1; } 
    static int obtainNumber() { return 0; } 
    static int obtainNumber() { return 2; } 
    static { 
     System.out.println(obtainNumber()); 
    } 
} 

Gleiches Ergebnis:

javac A.java && java A 
0 
Exception in thread "main" java.lang.NoSuchMethodError: main 

Ich dachte, dass Java eine textbasierte Sprache ist, von der ich annehme, dass dies unmöglich ist. Wie läuft Java welche Methode welche ist?

+1

Wenn Sie bemerken, ist derjenige, der mit der anderen Syntax hiliting von den anderen genommen wird. Vielleicht kann dich das aufgrund von versteckten Zeichen oder Grammatikquirlen auffallen. – hexafraction

+1

Warum sollte jemand das tun? Es ist wie ein Zaubertrick, der auf dem Programmierer gespielt wird. – Shoe

+0

@Jim von Batman The Dark Knight: * Manche Männer wollen einfach nur die Welt brennen sehen *. –

Antwort

6

Versteckte Zeichen. Der Quellcode ist äquivalent zu

static int obtainNumber() { return 42; }

static int obtain\ufeffNumber() { return 3; }

static int obtain\ufeff\ufeffNumber() { return -1; }

diese Art von Problemen sind, meine Quelldateien streng US-ASCII zu vermeiden. Ich möchte sicher sein, dass die Zeichen, die ich sehe, genau die Zeichen sind, die der Compiler sieht.

+8

Lässt mich denken, dass er das absichtlich gemacht hat ... –

+0

Wow, ich denke, der letzte Programmierer war ein bisschen verärgert ... – Michael

8

ich dies nur in meinem IDE kopiert/eingefügt und obwohl es ein Wunder war, dann, wenn man versucht, die Datei eine Fehlermeldung Ausgabe Clearing dieses erschien zu speichern:

speichern konnte nicht vollständig sein. Versuchen Sie Datei> Speichern unter ..., wenn das Problem weiterhin besteht.

Grund: Einige Zeichen können nicht mit "Cp1252" Zeichencodierung zugeordnet werden. Ändern Sie entweder die Codierung oder entfernen Sie die Zeichen, die nicht von der Zeichensatzkodierung "Cp1252" unterstützt werden.

Also, diese Methoden haben nicht den gleichen Namen, verwenden Sie einfach Zeichen, die gleich aussehen.

Weitere Informationen zu Zeichencodierung im Zusammenhang auf Java-Quelldateien:

+0

@ downvoter erklären Sie mindestens Ihre Gründe zum Downvote. –

1

Mein original Kommentar:

Wenn Sie bemerke, das auf Das, was genommen wird, ist das mit der anderen Syntax, die von den anderen hilitiert.Vielleicht kann dich das aufgrund von versteckten Zeichen oder Grammatikquirlen auffallen.

Ich klebte dies in Eclipse und bemerkte ein wenig mehr Charakter. Ich warf meine gespeicherte Datei (in CP1252) in einen Hex-Editor und fand eine Byte-Reihenfolge-Markierung.

Wenn ich schaute, CP1252 hat keine Byte-Reihenfolge-Marke, aber die Zeichen sind selbst in CP1252. Möglicherweise wurde ein Unicode-Zeichen eingegeben.

Wenn ich genauer hinsah, hatte eine andere Methode eine andere Reihenfolge Byte-Reihenfolge in einer anderen Byte-Reihenfolge.

Wie sie entstanden sind, werden wir nie erfahren. Wir wissen jedoch, dass der Compiler die ohne die Byte-Reihenfolge-Markierung nimmt.

Sie sollten das Projekt auf Codierungsprobleme überprüfen, insbesondere wenn es von anderen Systemtypen oder älteren Speichermedien wiederhergestellt wurde, die fehlerhaft sein könnten oder älteren Geräten ausgesetzt waren.

Wir müssen wirklich mit diesem FGITW Verhalten über Meta irgendwann jetzt beschäftigen.

Verwandte Themen