人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Javaの質問です。あるツールを使うとJavaのクラスファイルがいくつか入ったJARが出力されます。しかしそれらのクラスファイルはデフォルト・パッケージに入っています。Java1.4以降ではデフォルト・パッケージからのインポートができなくなったので、このJARをビルドパスに入れても肝心のクラスをインポートして使うことが出来ません。JARファイルを一度解凍して勝手にフォルダを作ってクラスファイルを移動してみたりしたのですが、ClassDefNotFoundErrorになります。クラスファイル自信が持っている「自分がどのパッケージにいるか」という情報と矛盾するからでしょうかね…。

なにか解決方法はあるでしょうか?

●質問者: westfish
●カテゴリ:コンピュータ
✍キーワード:JAR Java いるか インポート クラス
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● b-wind
●35ポイント

ツールの方で何とかするのが正攻法だと思うけど。

逆コンパイルすると言う手も有る。

http://home.f02.itscom.net/soukyoku/jtips/jad.html]

◎質問者からの返答

やっぱりそうですよねぇ。

実はコンパイルされる前の(ツールによって生成された)ソースも手に入るので、それらにパッケージ宣言を付け足してコンパイルしてJARにまとめるツールを作ればいいわけですが…うーむ。

やっぱりコンパイルされてしまったらいじるのは至難ですか。


2 ● quintia
●35ポイント

import に書けないだけで、A.class を classpath がとおったフォルダに置いておけば、Class. forName("A") でデフォルトパッケージのクラスAをClassLoaderに読み込ませることはできます。

Class#newInstance() でのインスタンスの生成もできます。

とここまでは確認済。

それがjarに入っている場合は確認してませんが、classpathが通ってさえいれば同じ様にできるのではないかなあ、と楽観視してます。

で、ここからはアイデア。


頻繁に使わないし頻繁に呼び出されることもないケース

リフレクション経由で使う。


色々な所で使うが頻繁に呼び出されることはないケース

リフレクション経由で呼び出すラッパーを作る。


ほとんど依存していると言ってもいいぐらい使っているケース

名前付きpackage に(アプリ本体とは別の package にした方が依存関係を集約できていいと思う) interface InterfaceA を作って、A のメソッドとフィールド変数のget/setメソッドを定義。

デフォルトパッケージに class WrapperA implements InterfaceA を作って、Aのインスタンスを生成した後、メソッドは全部Aに委譲してしまう様に実装。

名前付きpackageの方にユーティリティメソッド

public static InterfaceA newInstaceA() {
 Class c = Class.forName("WrapperA");
 return (InterfaceA)c.newInstance();
}

の様な感じのメソッドを作っておくとして、本体プログラムは InterfaceA を相手にするように書く。


というような感じにするといいのではないでしょうか。

◎質問者からの返答

おおー、なるほど

importができなくても、リフレクションで取得することはできてしまうわけですね!それは気づきませんでした!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ