Cómo importar una clase desde un paquete predeterminado


Posible duplicado: ¿Cómo acceder a las clases java en el paquete predeterminado?


Estoy usando Eclipse 3.5 y he creado un proyecto con alguna estructura de paquetes junto con el paquete predeterminado. Tengo una clase en el paquete predeterminado - Cálculos.java y quiero hacer uso de esa clase en cualquiera de los paquetes (por ejemplo en com.company.calc). Cuando intento hacer uso de la clase que está en el paquete predeterminado, me está dando un error de compilador. No es capaz de reconocer la clase en el paquete predeterminado. ¿Dónde está el problema?

Cálculos.java - código fuente

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

No puedo poner mi clase en ningún otro paquete. Esta clase tiene algunos métodos nativos que se implementan en Delphi. Si pongo esa clase en cualquiera de las carpetas, tendré que hacer cambios a esa DLL que quiero evitar (realmente - no puedo). Es por eso que puse mi clase en el paquete predeterminado.

Author: Community, 2010-02-03

9 answers

Del lenguaje Java spec :

Es un error de tiempo de compilación importar un tipo del paquete sin nombre.

Tendrás que acceder a la clase a través de reflexión o algún otro método indirecto.

 73
Author: McDowell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-03 16:02:05

Las clases en el paquete predeterminado no se pueden importar por clases en paquetes. Esta es la razón por la que no debe usar el paquete predeterminado.

 39
Author: matt b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-03 15:59:55

Hay una solución para su problema. Puedes usar la reflexión para lograrlo.

Primero, crea una interfaz para tu clase de destino Calculatons:

package mypackage;

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

}

A continuación, haga que su clase de destino implemente esa interfaz:

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

Finalmente, use reflexión para crear una instancia de la clase Calculations y asignarla a una variable de tipo CalculationsInterface:

Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it 
double res = api.GetProgress(10);
 6
Author: Mohammad Banisaeid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-29 09:45:57

Puedo darte esta sugerencia, Por lo que sé de mi experiencia en programación en C y C++ , Una vez, cuando tuve el mismo tipo de problema, lo resolví cambiando la estructura escrita dll en ".C " cambiando el nombre de la función que implementó la funcionalidad nativa de JNI. por ejemplo, si desea agregar su programa en el paquete " com.mypackage", Se cambia el prototipo de la implementación del JNI ".C " Función/método del archivo a este:

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
}

Ya que soy nuevo a delphi, no puedo garantizarle pero diré esto finalmente, (aprendí pocas cosas después de googlear sobre Delphi y JNI): Pídele a aquellas personas (Si no eres tú) que proporcionaron la implementación de Delphi del código nativo que cambien los nombres de las funciones a algo como esto:

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;

Pero, un consejo final: Aunque tú (si eres el programador de delphi) o ellos cambiarán los prototipos de estas funciones y recompilarán el archivo dll, una vez compilado el archivo dll, no podrás cambie el nombre del paquete de su archivo "Java" una y otra vez. Porque, esto requerirá de nuevo que usted o ellos cambien los prototipos de las funciones en delphi con prefijos cambiados (por ejemplo, JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

Creo que esto resuelve el problema. Gracias y saludos, Harshal Malshe

 4
Author: Harshal Malshe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-14 10:02:03

De algunos donde encontré a continuación: -

De hecho, puedes.

Usando la API de reflections puede acceder a cualquier clase hasta ahora. Al menos yo era capaz de:)

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

String fooReturned =
    (String) fooMethod.invoke(fooClass.newInstance(), "I did it");
 3
Author: Adnan Ghaffar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-09 00:24:12

Desafortunadamente, no se puede importar una clase sin que esté en un paquete. Esta es una de las razones por las que está altamente desaconsejado. Lo que yo intentaría es una especie de proxy put pon tu código en un paquete que cualquier cosa pueda usar, pero si realmente necesitas algo en el paquete predeterminado, haz que sea una clase muy simple que reenvíe las llamadas a la clase con el código real. O, aún más simple, que se extienda.

Para dar un ejemplo:

import my.packaged.DefaultClass;

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

public class DefaultClass {

   // Code here

}
 1
Author: Jon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-09 00:22:17

Crear un nuevo paquete Y luego mover las clases del paquete predeterminado en nuevo paquete y usar esas clases

 -1
Author: Khushboo Kashyap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-31 12:04:07
  1. Crea un nuevo paquete.
  2. Mueva sus archivos del paquete predeterminado al nuevo.
 -2
Author: Evgueni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-09 19:12:03
  1. Cree un paquete (carpeta) "raíz" en su proyecto, por ejemplo.

    Fuente del paquete; (.../ path_to_project / source/)

  2. Mueve a tu clase.class en una carpeta de origen. (.../ path_to_project / source / YourClass.class)

  3. Importar así

    Importar fuente.YourClass;

 -2
Author: Andrey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-23 09:13:39