¿Llamar a los métodos estáticos a través de un objeto “mala forma”? ¿Por qué?

En una pregunta reciente, alguien preguntó sobre los métodos estáticos y una de las respuestas indicó que generalmente los llamas con algo como:

MyClassName.myStaticMethod(); 

Los comentarios sobre eso también indicaron que también podría llamarlo a través de un objeto con:

 MyClassName myVar; myVar.myStaticMethod(); 

pero que se consideraba mala forma.

Ahora me parece que hacer esto realmente me puede hacer la vida más fácil, así que no tengo que preocuparme por lo que es estático o no (a) .

¿ Hay algún problema con llamar funciones estáticas a través de un objeto? Obviamente, no querrás crear un objeto completamente nuevo solo para llamarlo:

 Integer xyzzy; int plugh = xyzzy.parseInt ("42", 10); 

Pero, si ya tiene un objeto del tipo deseado, ¿hay algún problema al usarlo ?


(a) Obviamente, no puedo llamar a un método no estático con:

 MyClassName.myNonStaticMethod(); 

pero ese no es el problema que estoy preguntando aquí.

El comentario de mala forma proviene de las Convenciones de encoding para Java

Ver http://www.oracle.com/technetwork/java/codeconventions-137265.html#587

La razón para ello, si lo piensas, es que el método, al ser estático, no pertenece a ningún objeto en particular. Debido a que pertenece a la clase, ¿por qué querrías elevar un objeto en particular a un estado tan especial que parece poseer un método?

En su ejemplo particular, puede usar un número entero existente a través del cual llamar a parseInt (es decir, es legal en Java) pero que pone el foco del lector en ese objeto entero particular. Puede ser confuso para los lectores, y por lo tanto la guía es evitar este estilo.

En relación con esto, el progtwigdor le hace la vida más fácil, le da la vuelta y pregunta qué le hace la vida más fácil al lector . Hay dos tipos de métodos: instancia y estática. Cuando ves una expresión Cm y sabes que C es una clase, sabes que m debe ser un método estático. Cuando ve xm (donde x es una instancia) no puede ver, pero parece un método de instancia y, por lo tanto, la mayoría de las personas reserva esta syntax solo por ejemplo.

En mi opinión, el caso de uso real que hace esto tan ilegible es algo como esto. ¿Qué imprime el siguiente código?

 //in a main method somewhere Super instance = new Sub(); instance.method(); //... public class Super { public static void method() { System.out.println("Super"); } } public class Sub extends Super { public static void method() { System.out.println("Sub"); } } 

La respuesta es que imprime “Súper”, porque los métodos estáticos no son virtuales. Aunque instance es-un Sub , el comstackdor solo puede ir al tipo de la variable que es Super . Sin embargo, llamando al método por instance lugar de Super , está sutilmente implicando que será virtual.

De hecho, un desarrollador que lea el método instance.method() deberá observar la statement del método (su firma) para saber a qué método se está llamando en realidad. Mencionas

me parece que hacer esto puede hacer mi vida más fácil, así que no tengo que preocuparme por lo que es estático o no.

¡Pero en el caso anterior, el contexto es realmente muy importante!

Puedo decir con bastante confianza que fue un error para los diseñadores del lenguaje permitir esto en primer lugar. Mantente alejado.

Es una cuestión de comunicación. Llamar a un método en una instancia implica que estás actuando en / con esa instancia particular, no en / con la clase de la instancia.

Puede ser muy confuso cuando tienes un objeto que hereda de otro objeto, anulando su método estático. Especialmente si te refieres al objeto como un tipo de su clase antecesora. No sería obvio en cuanto a qué método estás ejecutando.