2016-09-11 2 views
1

この質問は、「なぜあなたはこのようにしたいのですか?」以外の満足できる回答がなくても、Reserved words as variable or method namesに尋ねられました。私はそれをもう一度聞いて、それがなぜ必要なのかを説明する文脈を提供し、適切な解決策への方向性も提供します。予約語を変数に持つ動的クラスを作成する

私は制御できないデータベースのスキーマに合わせて動的にクラスを構築するコードを書いています。ほとんどの場合、コードはきちんと動作していますが、約0.1%の列のケースでは、Javaの予約語が列名として使用されています。次のコードは、クラスの動的フィールドを作成するために使用されています。

evalClass.addField( "public" + columnType + "" + columnName + ";"、 "evalClass));

ここでJavaを使用すると、この問題が発生しますが、JVMのバイトコードでは完全に正当なものでなければならないため、このフィールドを動的に作成し、バイトコード操作を使用してアクセスする方法が必要です。スペースや予約語を含む任意の文字列をサポートする方法でこれがどのように行われるかの例はありますか?ありがとう!

+0

その質問は絶対に満足のいく回答です:[* "いいえ、方法はありません" *](http://stackoverflow.com/a/424002/157247)あなたの質問とそのことの区別は、 *ソースコードレベルで*しようとしていない*。その情報をフォアグラウンドに移動するように編集することを提案し、最後に「私はこれを見ましたが、ソースコードを尋ねています。バイトコードレベルでそれを行うことを頼んでいます。ソースコードレベルでやってください。 " –

+4

これはなぜ必要なのかまだ分かりません。私が考えることができるすべての永続性アーキテクチャは、フィールド/ Beanのプロパティ名を任意の列名にマッピングするための簡単な手法を提供し、Javaキーワードフィールド名を避けることもその理由の1つです。もちろん、スキーマからクラスを生成していますが、その概念は同じです。なぜあなたのフィールド名は列名と同じでなければならないのですか?どうしてあなただけではないのですか?プレフィックスをすべてのフィールド名に(または予約語に)追加するか、代わりに何かを追加しますか? –

+3

クラスを生成することができたとしても、どのような目的を果たしますか?あなたが書いたソースコードでは、これらのフィールドを使用することはできませんでした。全体のことは、多くの時間を無駄にする本当に良い方法のように聞こえる。ジェイソンがあなたの永続性アーキテクチャに言及したマッピングを構築する時間を費やしてください(そして/あるいはあなた自身の永続性アーキテクチャを書いている理由を尋ねるかもしれません)。 –

答えて

2

あなたが立ち往生している部分は明確ではありません。どんなバイトコード操作ライブラリでもこれを行えるはずです。

たとえば、ASMを使用すると、文字列をvisitFieldに直接渡すだけです。飛び降りるようなものはありません。

バイトコードレベルであっても、フィールド名にはまだいくつかの制限があることに注意してください。特に、MUTF8エンコーディングでは65535バイトを超えることはできません。

1

JavassistのソースレベルのAPIが動作しない唯一の方法を選択しました。識別子を使用してソースコードを構築する場合、識別子はソースコードの規則に準拠している必要があります。さらに、意図を再構成するために再び解析されなければならないソースコードを構築するために既に知られている意図された構造を使用することは、バイトコードを処理する最も非効率的な方法である。

これらの制限を回避するにはBytecode level APIを使用できます。副次的なことに、他のほとんどのバイトコード処理ライブラリには、ソースレベルのAPIがまったくないため、最初からバイトコードレベルのAPIを使用していました。

あなたの前提を再考する必要があります。リフレクションやその他の生成コードでしかフィールドにアクセスできない生成されたクラスは、例えば、識別子と値または配列から本質的に列を位置に関連付ける配列にマッピングされます(HashMap)。

+0

確認のおかげで、Javassistは必要な機能を簡単に手に入れることができたようで、99.9%のケースでは機能していました。この特定の機能はクラスの設定に使用する必要があるだけなので、パフォーマンスは主要な要素ではありませんでした。前提として、このコードはJDBCレベルのドライバレベルのコードであり、フィールドを制御するのではなく、データベースにあるものと一致するフィールドに依存する他のコードも使用しています。したがって、フィールド名を変更するだけでは、この作業を行うよりも痛いことになります。 –

+0

ソースレベルのAPIは、パフォーマンス面でより高価なだけでなく、エラーを導入する可能性も広がります。キーワードに一致するフィールド名に敏感であるだけでなく、タイプ名に一致する名前のフィールドを追加すると、* next *宣言が誤って失敗する可能性があります。 – Holger

関連する問題