¿Cómo llamar a getClass() desde un método estático en Java?
Tengo una clase que debe tener algunos métodos estáticos. Dentro de estos métodos estáticos necesito llamar al método getClass() para realizar la siguiente llamada:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
Sin embargo Eclipse me dice:
Cannot make a static reference to the non-static method getClass()
from the type Object
¿Cuál es la forma adecuada de corregir este error de tiempo de compilación?
La respuesta
Simplemente use TheClassName.class
en lugar de getClass()
.
Declaración de registradores
Dado que esto recibe tanta atención para un caso de uso específico (para proporcionar una manera fácil de insertar declaraciones de registro), pensé en agregar mis pensamientos al respecto. Los marcos de registro a menudo esperan que el registro esté restringido a un contexto determinado, por ejemplo, un nombre de clase completo. Por lo tanto, no se pueden copiar y pegar sin modificaciones. En otras respuestas se proporcionan sugerencias para declaraciones de registros seguras para pegar, pero tienen desventajas, como inflar el código de bytes o agregar introspección en tiempo de ejecución. No recomiendo estos. Copiar y pegar es una preocupación del editor , por lo que una solución de editor es la más apropiada.
En IntelliJ, recomiendo agregar una plantilla en vivo:
- Utilice "log" como abreviatura
- Úselo
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
como texto de plantilla. - Haga clic en Editar variables y agregue CLASE usando la expresión
className()
- Marque las casillas para reformatear y acortar los nombres de FQ.
- Cambie el contexto a Java: declaración.
Ahora, si escribes log<tab>
, se expandirá automáticamente a
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
Y reformatee y optimice automáticamente las importaciones para usted.
En cuanto al ejemplo de código de la pregunta, la solución estándar es hacer referencia explícita a la clase por su nombre, e incluso es posible prescindir de getClassLoader()
la llamada:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
Este enfoque todavía tiene la desventaja de que no es muy seguro contra errores de copiar y pegar en caso de que necesite replicar este código en varias clases similares.
Y en cuanto a la pregunta exacta del título, hay un truco publicado en el hilo adyacente :
Class currentClass = new Object() { }.getClass().getEnclosingClass();
Utiliza una Object
subclase anónima anidada para controlar el contexto de ejecución. Este truco tiene la ventaja de ser seguro para copiar y pegar...
Precaución al usar esto en una clase base de la que otras clases heredan:
También vale la pena señalar que si este fragmento tiene la forma de un método estático de alguna clase base, entonces currentClass
el valor siempre será una referencia a esa clase base en lugar de a cualquier subclase que pueda estar usando ese método.