2016-09-11 3 views
1

Diese Frage wurde einmal ohne eine befriedigende Antwort neben "warum möchten Sie das tun" um Reserved words as variable or method names. Ich werde es noch einmal stellen und einen Kontext bereitstellen, der erklärt, warum es notwendig ist, und sogar die Richtung zu einer richtigen Lösung.Erstellen Sie dynamische Klassen mit reservierten Wörtern als Variablen

Ich schreibe Code, der Klassen dynamisch erstellt, um dem Schema einer Datenbank zu entsprechen, auf die ich keine Kontrolle habe. In den meisten Fällen funktioniert der Code sauber, aber in etwa 0,1% der Spaltenfälle werden reservierte Wörter in Java als Spaltennamen verwendet. Der folgende Code wird verwendet, um das dynamische Feld in der Klasse zu erstellen:

evalClass.addField (CtField.make ("public" + columnType + "" + columnName + ";" evalClass "));

Nun, mit Java die Sprache, dies führt zu einem Problem, jedoch in JVM-Byte-Code, sollte dies völlig legal sein, so sollte es eine Möglichkeit geben, dieses Feld dynamisch zu erstellen und darauf zugreifen Byte-Code-Operationen verwenden. Hat jemand irgendwelche Beispiele dafür, wie dies auf eine Art und Weise geschehen würde, die beliebige Strings unterstützt, einschließlich Leerzeichen und reservierte Wörter? Vielen Dank!

+0

Diese Frage hat absolut eine befriedigende Antwort: [* "Nein, es gibt keinen Weg."] (Http://Stackoverflow.com/a/424002/157247) Der Unterschied zwischen Ihrer Frage und diesem ist, dass Sie Ich versuche es nicht auf der * Quellcodeebene *. Ich schlage vor, diese Informationen in den Vordergrund zu stellen, und erwähne nur die andere Frage am Ende: "Ich habe das gesehen, aber ich frage nach Quellcode und ich frage, ob wir das auf Bytecode-Ebene tun können, weil wir es nicht können mach es auf Quellcodeebene. " –

+4

Ich verstehe immer noch nicht, warum das notwendig ist. Jede Persistenzarchitektur, die ich mir vorstellen kann, bietet einfache Techniken zum Zuordnen von Feld/Bean-Eigenschaftsnamen zu beliebigen Spaltennamen, und das Vermeiden von Java-Schlüsselwortfeldnamen ist einer der Gründe dafür. Sicher, Sie generieren Klassen aus einem Schema, aber das Konzept ist das gleiche. Warum müssen Ihre Feldnamen mit Spaltennamen übereinstimmen? Warum gehst du nicht gerade z. Fügen Sie allen Ihren Feldnamen (oder nur reservierten Wörtern) ein Präfix oder etwas hinzu? –

+3

Selbst wenn Sie die Klassen generieren könnten, welchen Zweck würden sie erfüllen? Sie konnten diese Felder in keinem von Ihnen geschriebenen Quellcode verwenden. Das Ganze klingt nach einer wirklich guten Möglichkeit, viel Zeit zu verschwenden.Verbringe diese Zeit damit, die von Jason genannten Abbildungen in deine Persistenz-Architektur aufzunehmen (und/oder dich vielleicht selbst zu fragen, warum du deine eigene Persistenz-Architektur schreibst). –

Antwort

2

Es ist nicht klar, an welchem ​​Teil Sie feststecken. Jede Bytecode-Manipulationsbibliothek sollte dies ermöglichen.

Wenn Sie beispielsweise ASM verwenden, übergeben Sie Ihre Zeichenfolge direkt an visitField. Es gibt keine Reifen zum Springen oder so.

Beachten Sie, dass selbst auf Bytecode-Ebene noch einige Einschränkungen für Feldnamen bestehen. Insbesondere dürfen sie in der MUTF8-Codierung nicht mehr als 65535 Byte lang sein.

1

Sie haben den einzigen Weg gewählt, wo dies nicht funktioniert - die Source-Level-API von Javassist. Es sollte für Sie offensichtlich sein, dass wenn Sie den Bezeichner zum Erstellen von Quellcode verwenden, der Bezeichner den Quellcode-Regeln entsprechen muss. Außerdem ist die Verwendung der bereits bekannten beabsichtigten Struktur zum Konstruieren von Quellcode, der erneut analysiert werden muß, um die Absicht wiederherzustellen, die ineffizienteste Art der Verarbeitung von Bytecode.

Sie können die verwenden, um diese Einschränkungen zu überwinden. Als Nebenbemerkung haben die meisten anderen Bytecode-Verarbeitungsbibliotheken überhaupt keine API auf Quellcodeebene, so dass Sie von Anfang an eine API mit Bytecodeebene verwendet hätten.

Das heißt, Sie sollten Ihre Prämisse überdenken. Erzeugte Klassen, auf deren Felder nur über Reflektion oder anderen erzeugten Code zugegriffen werden kann, bieten keinen Vorteil gegenüber z.B. a HashMap Zuordnung von Bezeichnern zu Werten oder Arrays, die Spalten eindeutig mit Positionen verknüpfen.

+0

Danke für die Bestätigung, es schien, dass JavaSist der einfache Weg war, die benötigte Funktionalität zu bekommen, und für 99,9% des Falles funktioniert es. Da diese spezielle Funktionalität nur zum Einrichten der Klassen benötigt wird, war die Leistung kein primärer Faktor. Unter der Voraussetzung, dass dieser Code Code auf Treiberebene auf JDBC-Ebene ist, steuern wir die Felder nicht und verwenden auch anderen Code von einem Partner, der darauf angewiesen ist, dass die Felder denen in der Datenbank entsprechen. Daher wäre es viel schmerzhafter, die Feldnamen zu ändern, als dies einfach zu tun. –

+0

Nun, die Source-Level-API ist nicht nur teurer in Bezug auf die Leistung, es eröffnet auch mehr Möglichkeiten der Einführung von Fehlern. Es ist nicht nur empfindlich auf Feldnamen, die mit Schlüsselwörtern übereinstimmen, auch das Hinzufügen von Feldern mit Namen, die mit Typnamen übereinstimmen, kann dazu führen, dass die * next * -Deklarationen fälschlicherweise fehlschlagen. – Holger

Verwandte Themen