2011-07-10 6 views
11

Estoy desarrollando una aplicación en Java ME que deseo proporcionar como biblioteca. ¿No hay forma de ocultar las clases que no quiero que todos usen, pero aún es esencial para que la biblioteca funcione?Proporcionar una biblioteca Java, pero ocultando algunas clases

ACTUALIZACIÓN: Entiendo que puedo omitir el especificador público, pero ¿cómo puedo estructurar la biblioteca mientras desarrollo sin crear paquetes diferentes? Me gusta ver diferentes paquetes como carpetas diferentes, lo que me permite estructurar el código de una buena manera. Sin embargo, en algunos casos podría necesitar acceder a clases en otros paquetes, así que esto es bastante complicado. ¿Qué representa realmente el paquete? Una idea podría ser crear "interfaces", pero estas deben declararse públicas, lo que significa que los extranjeros también podrían implementar las interfaces destinadas solo para algunos procesos dentro de la biblioteca, ¿correcto?

+0

Hacer ellos "final". – daGrevis

+2

Hacer que la clase sea definitiva solo prohibirá la subclasificación. Todavía estará expuesto. – thunderflower

+0

Depende de lo que quiere decir con "querer" y de cuánto problema desea ir. Los modificadores de acceso son bastante fáciles de usar con la reflexión, por ejemplo. – CurtainDog

Respuesta

-3

Necesita proteger las clases que no quiere que se expongan. Esto los hará no utilizables desde el código del cliente. Lea más en the official docs

+0

La parte que necesita: omita la palabra clave 'public' en la declaración de clase, luego la clase solo es accesible para otras clases en el mismo paquete. – Brabster

+1

No se puede usar el modificador 'protected' para las clases, solo para miembros. La única manera de limitar el acceso a su clase es omitiendo el modificador 'public' haciéndolo visible solo dentro de su paquete. – Muzikant

1

Puede hacer las clases package protected que solo pueden ver otras clases en el mismo paquete. Si esto no es posible, puede usar ProGuard para modificar las clases y ocultar sus implementaciones.

+0

Gracias, sí, investigaré ProGuard –

+0

No puede usar el modificador 'protected' para las clases, solo para miembros. La única manera de limitar el acceso a su clase es omitiendo el modificador 'public' haciéndolo visible solo dentro de su paquete. – Muzikant

0

Sí, la hay.

Simplemente no declare esas clases public. En otras palabras, omiten la palabra clave public así:

class Internal { // rather than "public class Internal" 
    ... 
} 

Por defecto, las clases sólo son accesibles desde el paquete en el que se definen.

0

Vamos a considerar un ejemplo:

Si usted tiene una clase A, que desea ocultar, y una clase B, que utiliza la funcionalidad de la clase A, entonces usted puede hacer esto:

class B{ 
//Attribute and Methods 

    //Inner class A 
    class A{ 
     //Methods and Attributes. 
    } 

} 

Después de hacer esto, puede crear un Objeto de clase A dentro de un método de clase B y, por lo tanto, usarlo. Aunque la clase estará oculta de otras clases, aún podría ser utilizada.

+0

Hacer una clase interna no la oculta del mundo exterior. Aún puede importarlo y usarlo. Sin embargo, el acceso a nivel de paquete que ha utilizado ocultará las clases de otros paquetes. –

4

Para configurar la API de su biblioteca, querrá proteger todo lo que no desee exponer. No hacer esto simplemente omitir el modificador de acceso:

class fooBar { 
    // do stuff here  
} 

Esto establecerá el acceso de clases como 'por defecto', que permite el acceso desde dentro del mismo paquete, así como de cualquier clase que subclase fooBar.

Dentro de sus clases también querrá bloquear el acceso a sus métodos y miembros marcándolos ya sea private, protected u omitiendo el modificador para que sean 'predeterminados' según sea necesario.

  • private permitirá el acceso de la clase contenedora solamente;
  • 'predeterminado' (sin modificador) permite dentro de la clase que contiene y el paquete que contiene; y
  • protected permitirá el acceso dentro de la misma clase, paquete y cualquier subclase.

Para cualquier cosa que usted ha expuesto (public) también es una buena práctica para marcarlo como final si no está diseñado para ser anulado.

Básicamente, bloquea todo lo que puedas. Las API más pequeñas son más fáciles de usar y más difíciles de romper. Si encuentra que algo debe exponerse en el futuro, hágalo en el futuro. Es mucho más fácil expandir una API en lugar de desaprobar partes de ella.

+2

¡Gracias! Pero como dices, solo puedo usar la clase fooBar desde dentro del mismo paquete. ¿Cuál es la forma habitual de estructurar un proyecto de Java? He estado creando paquetes basados ​​en diferentes cosas que hacen las clases. Por ejemplo, tengo un paquete que llamo com.comms donde almaceno rutinas y clases para transmitir a través de sockets. Luego tengo otro paquete (como nivel de aplicación) que usa el paquete de comunicaciones. Pero supongo que para crear una API como esta, ¿debería tener todas las clases dentro del mismo paquete? –

+3

Sí, ¿cómo puede hacerlo cuando tiene una biblioteca con varios paquetes? –

+0

Por defecto, las clases tienen visibilidad predeterminada y, por lo tanto, la visibilidad se encuentra solo dentro del paquete. También puede configurarlo para que esté protegido explícitamente y también servirá para el mismo propósito, – Tarun

0

Si Java 9 es posible, use Jigsaw modules. De lo contrario, coloque cada clase en el mismo paquete, con acceso a nivel de paquete para las clases ocultas, y use Maven modules para organizarlas.

He hecho exactamente eso en mi proyecto llamado coronata, una biblioteca de java de Wii Remote. Casi todas las clases están en el paquete com.github.awvalenti.bauhinia.coronata, pero en diferentes módulos (que aparecen como proyectos en el IDE).

Las clases visibles son públicas. Ellos están en módulos:

  • coronata-api
  • coronata-builder
  • coronata-demos
  • coronata-lib

clases ocultos tienen acesss a nivel de paquete. Se encuentran en los módulos:

  • coronata-common
  • coronata-implementation-bluecove
  • coronata-implementation-wiiusej
Cuestiones relacionadas