すべてのコードを Java ファイルに書き込み、Java ファイルをクラス ファイルにコンパイルしてから、URLClassLoader を使用してクラス ファイルをロードすることにより、Java プログラムで動的クラスを生成しています。これに関する問題は、コンピューターに多くのファイルが作成されることです。「仮想ファイル」(ファイルオブジェクト)のみを作成し、実際のファイルを生成しないでこれを行う方法はありますか?これは、時間がかかり、汚れていて非効率的であるように見えるためです。
3 に答える
ClassLoaderクラスを見ると、実際の一連のバイトからクラスを定義するメソッドがあります。
私はこの低レベルのクラスローダーを使用したことがないことを認めますが、これはテンプレートパターンであり、基本のClassLoaderクラスが生のバイトコードに基づいてVMにクラスを作成する方法を知っていることを理解しています。子クラスは、特定のクラスのバイトコードがどこにあるかを把握する責任があります。
したがって、解決策は、URLClassLoaderの使用を完全に停止し、ClassLoaderを自分で拡張することです。
バイト コード生成および操作ライブラリを使用すると、メモリ内でその場でクラスを変更および生成できます。Javassistは、Java 構文を使用できるため、おそらく最も簡単に開始できます。
また、スタンドアロン コンパイラ全体よりも軽量になる傾向があります。
(より)簡単な解決策は、次のことです。
- クラス ファイルを共通ディレクトリにコンパイルします。
ClassLoader
拡張するカスタムを作成するClassLoader
- これ
ClassLoader
を使用して、.class ファイルを読み込みます。
ここから始めましょう。オブジェクトにバイト コードを挿入する演習は、読者の演習として残しておきます。(少し手を加えればそれほど難しくありませんSimpleFileVisitor
。Java.NIO を 調べてください。 )
public class CustomClassLoader extends ClassLoader {
@Override
public Class findClass(String binaryClassName) {
byte[] b = customLoadClassData(binaryClassName);
return defineClass(binaryClassName, b, 0, b.length);
}
private byte[] customLoadClassData(String binaryClassName) {
// Be sure to read in the specific .class file you want.
// A tip is to handle this *outside* of this class.
}
}
その後、次のように使用できます。
CustomClassLoader loader = new CustomClassLoader();
Class clazz = loader.findClass("com.stackoverflow.some.binary.name");
...例外をスローしたり、null を返さなかったりした場合に限ります。