¿Por qué tener métodos estáticos privados?


68

Solo quería aclarar una pregunta que tengo. ¿Cuál es el punto de tener un método estático privado en lugar de un método normal con visibilidad privada?

Hubiera pensado que una ventaja de tener un método estático es que se puede llamar sin una instancia de una clase, pero dado que es privado, ¿hay incluso un punto para que sea estático?

La única razón por la que puedo pensar es que ayuda a comprender conceptualmente el método a nivel de clase en lugar de a nivel de objeto.


32
Sí, hay una razón Sus métodos estáticos públicos / predeterminados aún pueden llamar a sus estadísticas privadas. Si los métodos estáticos deben usarse en absoluto y si es apropiado usar métodos privados de cualquier tipo, son preguntas separadas, así que tenga cuidado de no mezclarlas con esta pregunta.

2
Ejemplo rápido: método de fábrica utilizado por una clase interna que impide la invocación de otras clases (debe seguir el método de fábrica para obtener una instancia de la clase).

2
@MattFenwick: debe publicar esto como respuesta.
Doc Brown

9
Al hacer que un método sea estático, también está diciendo que no lee ni escribe en variables de instancia. Un método que no interactúa con las variables de instancia a menudo es más fácil de mover y refactorizar a otros lugares.
Mark Rogers

1
No olvide que, independientemente de si un método estático es privado, interno o público, todavía no es seguro para subprocesos sin un esfuerzo específico de sincronización de código de su parte.
Craig

Respuestas:


70

La característica de ser estático es independiente de la visibilidad.

Las razones por las que querrás tener un método estático (algunos códigos que no dependen de miembros no estáticos) seguirán siendo útiles. Pero tal vez no quieras que nadie / nada lo use, solo tu clase.


3
Creo que estás en el camino correcto, pero también creo que te estás perdiendo un punto clave. La mayoría de los métodos estáticos tienen cero efectos secundarios (son efectivamente funciones, no métodos), por eso se hacen estáticos en primer lugar. El argumento en contra de que sean privados es "Si no tienen efectos secundarios, por qué no hacerlos públicos para promover la reutilización del código". Ese es el punto clave: cuando lo hacemos privado, generalmente es porque queremos que reutilices toda la clase que usa ese método privado, no solo ese método.
corsiKa

Debo decir que nunca he hecho eso o visto ese comportamiento. Las pocas veces que lo hice fue para métodos auxiliares a clases públicas estáticas.
Miyamoto Akira

1
@corsiKa: los efectos secundarios no son el problema. Hacer que un miembro estático de una clase no sea privado promete efectivamente que cada versión futura de una clase incluirá el mismo método del mismo nombre que hace lo mismo. Si las necesidades cambian, y una versión futura de la clase puede no necesitar un método que funcione exactamente como el actual, un método privado puede reemplazarse de manera segura por uno que satisfaga mejor las nuevas necesidades de la clase. Como un simple ejemplo, supongamos que una clase necesita un método que toma una cadena y realiza sustituciones como <a &lt;, etc. Cuando está escrito ...
supercat

1
... las cadenas que ésta es enviada se sabe que no contiene ningún símbolo de unión, y por lo tanto no convierte &a &amp;[si yo escribiendo el código, me gustaría convertir &a &amp;incluso si yo no esperaba que fuera necesario, pero supongamos no lo hace]. Que más tarde se convierte en necesaria para manejar los símbolos de unión, pero el método es público, el cambio que se expanda &a &amp;podría romper el código externo que lleva a cabo su propia &-a- &amp;sustitución. Sin embargo, si el método es privado, se podría arreglar para manejarlo &sin causar problemas para ningún código externo.
supercat

Eso es un problema interesante por decir lo menos, pero no veo la forma en que sea estática hace que sea ningún más de un problema que no es estática, lo que es clave para este problema. Si seguimos su lógica, todo en todas partes volvería a implementar todo porque "Dios mío, ¿qué pasa si hay algún error o los requisitos cambian algún día?"
corsiKa

26

Una razón bastante común (en Java) sería la inicialización de variables de campo inmutables en un constructor mediante el uso de un private staticmétodo simple para reducir el desorden del constructor.

  • Lo es private: las clases externas no deberían verlo.
  • Es static: puede realizar alguna operación, independiente 1 del estado de la clase de host.

Sigue un ejemplo un tanto artificial ...

p.ej:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 Suponiendo que no tiene interacción con otras staticvariables.


15
Esto es aún más valioso cuando necesita pasar argumentos derivados (calculados) al constructor de una superclase. La super(...)llamada debe ser la primera línea del constructor de su clase, por lo que no puede declarar variables locales para ayudarlo a determinar qué pasar a la súper llamada. Sin embargo, puede llamar a métodos estáticos (privados), que usan tantas líneas como sea necesario para calcular el valor que se pasa al superconstructor.
Andrzej Doyle

tenga en cuenta que existe la posibilidad de un bloque de inicializador estático
Franz Ebner

13

Un caso de uso común para un private staticmétodo es un método de utilidad que es

  1. solo usado por esa clase
  2. es independiente del estado interno de esa clase

12

Verá que tiene algunas líneas de código que se repiten en muchos de sus métodos, por lo que decide extraerlos a un solo método, ya que el código duplicado no es bueno.

Hace que el método sea privado ya que no está diseñado para un uso generalizado y no desea que un código no relacionado lo llame. (Debate este punto en los comentarios ...)

Como el método no accede a ningún campo de instancia, puede hacerse estático, al hacerlo estático, lo hace más fácil de entender y tal vez incluso un poco más rápido.

Entonces ... (Tal vez ahora, tal vez más tarde, tal vez nunca)

Una vez que el método se ha vuelto estático, está claro que se puede sacar de la clase, por ejemplo, a una clase de unidad.

También es fácil transformarlo en un método de instancia de uno de sus parámetros, a menudo aquí es donde debería estar el código.


Me gusta esta respuesta, pero ¿tiene alguna referencia actualizada para esto? "y tal vez incluso un poco más rápido"
Magnilex

@Magnilex, el puntero "this" no se pasa a los métodos de clase estática, por lo tanto, tenderán a ser más rápidos que los métodos de instancia estática, a menos que el compilador detecte que "this" no se usa en el método de instancia (poco probable).
Ian

2

Puedo pensar en al menos dos razones por las que necesitarías un método privado estático en una clase.

1: Sus instancias tienen motivos para llamar a un método estático que no desea que se llame directamente, quizás porque comparte datos entre todas las instancias de su clase.

2: Sus métodos estáticos públicos tienen subrutinas a las que no desea que se llame directamente. El método todavía se llama sin una instancia, solo que no directamente.

Por supuesto, "ayuda a que la clase tenga sentido" es una buena razón por sí sola.


1

En general, si encuentro que estoy escribiendo métodos estáticos privados, lo tomo como una indicación de que hay algo que debería haber modelado por separado.

Dado que no están vinculados al estado de una instancia de objeto particular, una colección de métodos estáticos públicos y privados podría formar una clase completamente separada con sus propios métodos semánticos y no estáticos.

(Otro consejo es que si encuentro que tengo muchos métodos estáticos (públicos y privados) que tienen un parámetro común de algún tipo, podrían ser mejores como miembros de ese tipo).

Entonces, para responder a su pregunta, los métodos estáticos privados aparecen cuando una clase proporciona un grupo de métodos relacionados que son independientes de una instancia de esa clase. (... y como son independientes, pueden estar mejor en su propia clase).


-1

Un ejemplo muy simple en el que puedo pensar es, si quieres hacer algún procesamiento en los argumentos de entrada (o alguna manipulación) que se pasan a la función principal. Por lo tanto, en este caso, si el procesamiento es grande y la misma funcionalidad no se usará en ningún otro lugar, tendrá sentido tener una función privada, ya que no se usará / invocará desde otro lugar + estático, ya que main es estático.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.