tipos - que es una libreria en java
Pros y contras de las clases privadas de paquetes en Java? (8)
Estoy aprendiendo Java recientemente, y me encontré con la noción de clases package-private
de package-private
, que es la predeterminada si no especificamos nada. Pero luego me di cuenta:
Pocas veces veo el uso de la clase paquete privado. ¿Hay alguna razón para esto, por ejemplo, tiene serios inconvenientes, es redundante o simplemente no estoy leyendo lo suficiente? ¿Hay argumentos fuertes a favor o en contra de su uso?
Si realmente no es útil en la mayoría de los casos, ¿por qué sería el valor predeterminado?
¿En qué situación deberíamos usar package-private en el mundo real? Es decir, ¿cuándo sería irremplazable?
En otras palabras, ¿cuáles son los principales pros y contras del modificador predeterminado package-private?
"Paquete privado" se usa cuando tiene varios paquetes, y significa que otras clases en el mismo paquete pueden acceder a esa clase o miembro de la clase como "público", las clases en otros paquetes no pueden acceder, es como "privadas como ellos".
1 - Depende de la arquitectura: generalmente, si está escribiendo código solo para usted y en pequeños proyectos, probablemente no lo use. En proyectos más grandes, puede ser útil asegurarse de que puede controlar dónde y cómo se llaman ciertos métodos.
2 - Predeterminado (es decir, no público / protegido / privado) no es lo mismo que privado - es un 4to estado. Ver control de acceso de Java
3 - Puede hacer la vida más fácil cuando escribe bibliotecas que no desea que terceros confíen en cómo está implementando el código subyacente; solo hace que la API sea pública.
Además de la encapsulación, una de las principales ventajas de utilizar clases privadas de paquete es que no aparecen en el javadoc de su proyecto. Por lo tanto, si utiliza algunas clases de ayuda que no tienen otro uso que no sea ayudar a sus clases públicas a hacer algo que los clientes necesitan, tiene sentido hacer que los paquetes sean privados, ya que desea mantener las cosas lo más simples posible para los usuarios de la biblioteca.
Como ejemplo, puede echar un vistazo a una biblioteca que he desarrollado. El javadoc solo contiene 5 interfaces y 12 clases, aunque el código fuente tiene mucho más. Pero lo que está oculto es principalmente capas internas que no proporcionan ningún valor agregado para un cliente (por lo general, todas las clases base abstractas están ocultas).
También hay muchos ejemplos en el JDK.
Con respecto a la pregunta de "por qué sería el incumplimiento", en este contexto, el término "predeterminado" simplemente significa la ausencia de otro calificador. Supongo que podrían haber inventado otra palabra clave (ya se había tomado el "paquete"), pero no lo hicieron.
En el mundo real, utilizo el acceso predeterminado para las clases de utilidad y las clases abstractas que no quiero que las personas llamen o utilicen de otros paquetes. Digamos que tienes una interfaz y dos implementaciones concretas que se extienden desde alguna clase abstracta. Declaras tus dos clases concretas como finales porque no necesariamente quieres que las personas las subclasen (ver Java efectivo). Tampoco quieres que la gente mire con tu clase abstracta por la misma razón. Si usa el acceso predeterminado para la clase abstracta, las personas solo lo verán si colocan su clase en su paquete. No es a prueba de balas, pero creo que es un uso / ilustración razonable del acceso predeterminado. Dicho esto, el hecho de que no impida que los detalles se filtren como privados, es decir, no garantiza nada, significa que no es una convención particularmente útil.
Otra razón por la que no lo has visto se usa con más frecuencia es que las personas tienden a excluir las clases con acceso predeterminado de sus javadocs.
El nivel de acceso privado del paquete es más restrictivo que protected
: aún se puede acceder a los atributos y métodos protegidos simplemente subclasificando una clase. Los miembros protegidos son (o pueden estar) destinados a la herencia mientras que los miembros privados del paquete no lo son.
Los miembros privados del paquete se utilizan a menudo para que las clases multilí dentro de un paquete puedan acceder a los atributos o métodos (de utilidad) específicos de la implementación .
Buenos ejemplos de esto son el constructor privado de paquete de String
y la matriz de caracteres StringBuilder.value
:
/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
// assert share : "unshared not supported";
this.value = value;
}
Por lo tanto, las clases dentro del paquete java.lang
pueden crear nuevas Strings
eficiente si el contenido ya está presente en un char[]
sin comprometer la seguridad. No puede hacer esto desde su aplicación porque si pudiera, tendría acceso (referencia) a la matriz de caracteres interna de una String
que es inmutable (¡la reflexión no cuenta!).
En StringBuilder
(o más bien AbstractStringBuilder
donde viene la implementación), la matriz de caracteres que contiene el valor de valor actual char[] value
y un método de acceso a este char[] getValue()
también son paquetes privados, por lo que hay varios métodos de String
como contentEquals(StringBuffer sb)
y contentEquals(CharSequence cs)
pueden utilizar esto para una mayor eficiencia y comparaciones más rápidas sin exponer la matriz de caracteres interna al "mundo".
La respuesta corta es: es una forma un poco más amplia de privado.
Asumiré que está familiarizado con la distinción entre public
y private
, y por qué generalmente es una buena práctica hacer que los métodos y las variables sean private
si se van a usar exclusivamente internamente para la clase en cuestión.
Bueno, como una extensión de eso: si está pensando en crear su software de forma modular, puede pensar en una interfaz pública para su módulo , que tendrá múltiples clases dentro de ella colaborando entre sí. En este contexto, tiene mucho sentido hacer public
métodos si van a ser llamados por los consumidores; private
si son internos a una clase; y package private
si se utilizan para llamar entre las clases en este módulo, es decir, es un detalle de implementación de su módulo (como lo ven las personas que llaman en público) pero abarca varias clases.
Esto rara vez se usa en la práctica, porque el sistema de paquete resulta no ser tan útil para este tipo de cosas. Tendría que volcar todas las clases para un módulo dado en exactamente el mismo paquete, que para algo no trivial va a ser un poco difícil de manejar. Así que la idea es genial: hacer que un método sea accesible solo para un puñado de clases "cercanas", como una privacidad un poco más amplia, pero las restricciones sobre cómo se define ese conjunto de clases significa que es raramente utilizado / útil.
Tenga en cuenta que cuando habla de clases solo tiene dos opciones:
- clases públicas
- paquete de clases privadas
El concepto de "clase privada" no tiene sentido. (¿Por qué hacer una clase que no se usa en ninguna parte ?!)
Entonces, si tiene una clase para operaciones intermedias que no necesita exponerse a usuarios de API, se supone que debe declararla como "paquete privado".
Además, cuando define muchas clases en el mismo archivo fuente, solo se permite que una clase sea pública (su nombre coincide con el nombre del archivo .java). Si cualquier otra clase se define en el mismo archivo, debe ser "paquete privado".
Una cosa agradable sobre el paquete privado es que puedes usarlo para dar acceso a métodos que de otro modo considerarías clases de prueba privadas a unidades. La desventaja, por supuesto, es que otras clases en el paquete podrían llamarlo cuando realmente no deberían.