java - seticon - ¿Por qué no está disponible getClass() como método estático?
seticon java (8)
En contextos estáticos, ¿por qué no puede llamar a una versión estática de getClass()
(en lugar de tener que usar my.package.name.MyClassName.class
)?
¿No es el compilador lo suficientemente inteligente como para determinar cuándo usar métodos de objetos + cuándo usar métodos estáticos?
NOTA para mayor claridad:
No estoy diciendo que se deba usar una static getClass()
lugar del método no estático getClass()
(eso es algo obvio: si SpecialFoo
es una subclase de Foo
, entonces la getClass()
de un Foo
podría devolver a Foo.class
o SpecialFoo.class
o algo más y debe determinarse en tiempo de ejecución).
Estoy diciendo que me pregunto por qué no hay dos versiones de getClass()
, una que es un método estático que solo se aplica en un contexto estático, y el método regular no estático getClass()
. Si no es posible, entonces no es posible, y esa es la respuesta. Si es posible, pero simplemente no se ha hecho, entonces es una elección histórica, y tal vez haya una buena razón para ello. Eso es lo que me gustaría saber.
Sería genial declarar
final static Logger logger = LoggerFactory.getLogger(getClass());
en lugar de
final static Logger logger = LoggerFactory.getLogger(my.package.name.MyClass.class);
donde el primero podría copiarse literalmente de una clase a la siguiente, mientras que el segundo requiere que copie el nombre de la clase en cada archivo.
¡Cada objeto es una instancia de una clase en Java y ninguna clase puede ser una instancia de otra clase! Es por eso que getClass () no es estático ya que solo tiene sentido en el contexto de un objeto: estás tratando de encontrar para un objeto de qué clase es una instancia. Si era una función estática, se puede llamar fuera de un objeto, pero no tiene sentido escribir
String.getClass()
¡porque ya sabes que estás "preguntando" la clase String!
¿Un getClass()
estático getClass()
devolvería al objeto de clase la clase de la variable que contiene el objeto? Eso cambiaría la semántica de getClass()
. Ejemplo:
Interface foo = new FooImpl();
foo.getClass(); // returns Class<FooImpl> because the runtime type is FooImpl.
// If getClass() was static, it would return Class<Foo>.
Además de otras respuestas (que explican por qué no podemos crear un método estático con la misma firma que el método no estático ''getClass ()''), uno se preguntaría si sería posible tenerlo, por ejemplo una static Class getStaticClass()
modo que, por ejemplo, String.getStaticClass()
sería equivalente a String.class
. Pero, nuevamente, este método no podría ser un método "normal" ¿Dónde se definiría? en objeto? Entonces, ¿cómo sabría este método único qué devolver (String.class o Object.class) cuando se llamó como String.getStaticClass () o Object.getStaticClass ()? ¿Lo decidiría en tiempo de ejecución? De ninguna manera.
Un método estático no tiene sentido porque String.class
se conoce (resuelve) en el momento de la compilación. El método no tiene nada que hacer en tiempo de ejecución; tendrías que hacer algo de magia de compilación para que el resultado de esa llamada de método se resuelva en el momento de la compilación.
Porque si getClass()
sería estático, su código tendría que estar definido en una clase, probablemente Object
. Allí, no puede determinar la clase de llamadores y no hay una instancia de objeto que la llame.
Editar:
No se trata del nombre; Podría estar muy bien getClass2()
. Estoy diciendo que si define un método estático, no puede saber la clase que lo llama:
public class Object {
public static Class<?> getClass2() {
return ...?
}
}
Puedes usar este idioma
Class<?> cl=new Object(){}.getClass().getEnclosingClass();
Por ejemplo:
static class Bar {
public static void main(String[] args) {
Class<?> cl=new Object(){}.getClass().getEnclosingClass();
System.out.println(cl==Bar.class); //will print true
}
}
Usted puede implementar uno mismo. Obtener el stacktrace, y encontrar la clase que llama.
En realidad el logger lib podría implementarlo
static Logger logger = LoggerFactory.getLogger(); // auto detect caller class
Y nada más, porque no es legal tener una versión static
y no static
de un método (probablemente porque es legal, si no se recomienda, llamar a un método static
en un contexto no static
).
También me parece que tal método, aunque útil en el contexto de definir un registrador o lo que sea, podría ser confuso en otros contextos, como cuando se llama desde un método de instancia.
getClass () proporciona una funcionalidad diferente a la estática .class. Se utiliza para obtener la clase de tiempo de ejecución de la instancia a la que se llama.
Object o = new String();
o.getClass() // returns Class<String>
Object.class // returns Class<Object>