105

重複の可能性:default-packageのjavaクラスにアクセスする方法は?


私はEclipse3.5を使用しており、デフォルトのパッケージとともにいくつかのパッケージ構造を持つプロジェクトを作成しました。デフォルトパッケージに1つのクラス(Calculations.java)があり、そのクラスを任意のパッケージ(たとえば)で使用したいと思いますcom.company.calc。デフォルトのパッケージに含まれているクラスを使用しようとすると、コンパイラエラーが発生します。デフォルトパッケージのクラスを認識できません。問題はどこだ?

Calculations.java-ソースコード

public class Calculations {
    native public int Calculate(int contextId);
    native public double GetProgress(int contextId);
    static  {
        System.loadLibrary("Calc");
    }
}

クラスを他のパッケージに入れることはできません。このクラスには、Delphiで実装されているいくつかのネイティブメソッドがあります。そのクラスをいずれかのフォルダーに配置すると、回避したいDLLに変更を加える必要があります(実際にはできません)。そのため、クラスをデフォルトのパッケージに入れました。

4

9 に答える 9

92

Java言語仕様から:

名前のないパッケージから型をインポートすると、コンパイル時にエラーが発生します。

リフレクションまたはその他の間接的なメソッドを介してクラスにアクセスする必要があります。

于 2010-02-03T16:02:05.903 に答える
55

デフォルトパッケージのクラスは、パッケージのクラスからインポートできません。これが、デフォルトのパッケージを使用すべきではない理由です。

于 2010-02-03T15:59:55.797 に答える
8

問題の回避策があります。あなたはそれを達成するために反射を使うことができます。

まず、ターゲットクラスのインターフェイスを作成しますCalculatons

package mypackage;

public interface CalculationsInterface {  
    int Calculate(int contextId);  
    double GetProgress(int contextId);  

}

次に、ターゲットクラスにそのインターフェイスを実装させます

public class Calculations implements mypackage.CalculationsInterface {
    @Override
    native public int Calculate(int contextId);
    @Override
    native public double GetProgress(int contextId);
    static  {
        System.loadLibrary("Calc");
    }
}

最後に、リフレクションを使用してクラスのインスタンスを作成し、Calculationsそれを次のタイプの変数に割り当てますCalculationsInterface

Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it 
double res = api.GetProgress(10);
于 2016-09-29T09:38:22.667 に答える
5

私はあなたにこの提案をすることができます、私のCとC ++プログラミングの経験から知る限り、かつて私が同じような問題を抱えていたとき、私は「.C」ファイルのdll記述構造を変更することによってそれを解決しましたJNIネイティブ機能を実装した関数。たとえば、パッケージ「com.mypackage」にプログラムを追加する場合は、「。C」ファイルの関数/メソッドを実装するJNIのプロトタイプを次のように変更します。

JNIEXPORT jint JNICALL
Java_com_mypackage_Calculations_Calculate(JNIEnv *env, jobject obj, jint contextId)
{
   //code goes here
}

JNIEXPORT jdouble JNICALL
Java_com_mypackage_Calculations_GetProgress(JNIEnv *env, jobject obj, jint contextId)
{
  //code goes here
}

私はデルファイに慣れていないので、あなたを保証することはできませんが、最後にこれを言います(DelphiとJNIについてグーグルした後、いくつかのことを学びました):ネイティブのDelphi実装を提供した人々(あなたが1人でない場合)に尋ねてください関数名を次のようなものに変更するコード:

function Java_com_mypackage_Calculations_Calculate(PEnv: PJNIEnv; Obj: JObject; contextId: JInt):JInt; {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}
var
//Any variables you might be interested in
begin
  //Some code goes here
end;



function Java_com_mypackage_Calculations_GetProgress(PEnv: PJNIEnv; Obj: JObject; contextId: JInt):JDouble; {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}
var
//Any variables you might be interested in
begin
//Some code goes here
end;

しかし、最後のアドバイス:あなた(あなたがデルファイプログラマーの場合)または彼らはこれらの関数のプロトタイプを変更してdllファイルを再コンパイルしますが、dllファイルがコンパイルされると、あなたのパッケージ名を変更することはできません「Java」ファイルを何度も繰り返します。なぜなら、これもまた、プレフィックスが変更されたdelphiの関数のプロトタイプを変更する必要があるためです(例:JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

これで問題は解決すると思います。よろしくお願いいたします。HarshalMalshe

于 2010-03-14T10:02:03.747 に答える
5

私が以下で見つけたいくつかから:-

実際、できます。

リフレクションAPIを使用すると、これまでの任意のクラスにアクセスできます。少なくとも私はできました:)

Class fooClass = Class.forName("FooBar");
Method fooMethod =
    fooClass.getMethod("fooMethod", new Class[] { String.class });

String fooReturned =
    (String) fooMethod.invoke(fooClass.newInstance(), "I did it");
于 2014-04-09T12:01:23.957 に答える
3

残念ながら、パッケージに含まれていないクラスをインポートすることはできません。これが、非常に推奨されない理由の1つです。私が試したいのは一種のプロキシです。コードを何でも使用できるパッケージに入れますが、デフォルトパッケージに何かが本当に必要な場合は、実際のコードを使用してクラスに呼び出しを転送する非常に単純なクラスを作成します。または、さらに簡単に、拡張するだけです。

例を挙げると:

import my.packaged.DefaultClass;

public class MyDefaultClass extends DefaultClass {}
package my.packaged.DefaultClass;

public class DefaultClass {

   // Code here

}
于 2010-02-03T15:58:43.740 に答える
0

新しいパッケージを作成し、デフォルトパッケージのクラスを新しいパッケージに移動して、それらのクラスを使用します

于 2018-03-31T12:04:07.973 に答える
-1
  1. 新しいパッケージを作成します。
  2. ファイルをデフォルトのパッケージから新しいパッケージに移動します。
于 2015-05-09T18:54:55.750 に答える
-3
  1. たとえば、プロジェクトに「ルート」パッケージ(フォルダ)を作成します。

    パッケージソース; (... / path_to_project / source /)

  2. YourClass.classをソースフォルダーに移動します。(... / path_to_project / source / YourClass.class)

  3. このようにインポート

    source.YourClassをインポートします。

于 2014-05-12T10:58:28.323 に答える