¿Cómo llamar a getClass() desde un método estático en Java?

Resuelto Rama asked hace 12 años • 9 respuestas

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?

Rama avatar Nov 26 '11 07:11 Rama
Aceptado

La respuesta

Simplemente use TheClassName.classen 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ónclassName()
  • 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.

Mark Peters avatar Nov 26 '2011 00:11 Mark Peters

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 Objectsubclase 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 currentClassel valor siempre será una referencia a esa clase base en lugar de a cualquier subclase que pueda estar usando ese método.

Sergey Ushakov avatar Jul 01 '2013 04:07 Sergey Ushakov