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 hacer 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?
java
static-methods
Rama
fuente
fuente
getResource()
antes de que haya una instancia de una clase definida por el usuario (por ejemplo, no J2SE) a veces fallará. El problema es que el JRE usará el cargador de clases bootstrap en esa etapa, que no tendrá recursos de aplicación en la ruta de clase (del cargador bootstrap).Respuestas:
La respuesta
Solo use en
TheClassName.class
lugar degetClass()
.Declarando madereros
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 determinado contexto, digamos un nombre de clase completamente calificado. Por lo tanto, no son copiables sin modificaciones. En otras respuestas se proporcionan sugerencias para declaraciones de registro seguras para pegar, pero tienen inconvenientes como inflar el código de bytes o agregar introspección en tiempo de ejecución. No los recomiendo. Copiar y pegar es una preocupación del editor , por lo que una solución de editor es la más adecuada.
En IntelliJ, recomiendo agregar una plantilla en vivo:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
como texto de plantilla.className()
Ahora, si escribe
log<tab>
, se expandirá automáticamente aY reformatee y optimice automáticamente las importaciones por usted.
fuente
Log
en Android, que requiere que se suministre una etiqueta, generalmente el nombre de la clase. Y probablemente hay otros ejemplos. Por supuesto, puede declarar un campo para eso (que es una práctica común), pero aún así es copiar y pegar.CLASS
escribirclassName()
. Eso asegurará que $ CLASS $ se reemplace realmente con el nombre de la clase, de lo contrario, simplemente saldrá vacío.En cuanto al ejemplo de código en la pregunta, la solución estándar es hacer referencia a la clase explícitamente por su nombre, e incluso es posible hacerlo sin
getClassLoader()
llamar:Este enfoque todavía tiene una parte posterior de que no es muy seguro contra los errores de copiar / pegar en caso de que necesite replicar este código en varias clases similares.
Y en cuanto a la pregunta exacta en el título, hay un truco publicado en el hilo adyacente :
Utiliza una
Object
subclase anónima anidada para obtener el contexto de ejecución. Este truco tiene la ventaja de ser seguro para copiar / pegar ...Tenga cuidado al usar esto en una clase base que otras clases heredan de:
También vale la pena señalar que si este fragmento se forma como un método estático de alguna clase base, el
currentClass
valor siempre será una referencia a esa clase base en lugar de a cualquier subclase que pueda estar usando ese método.fuente
Class.getResource()
puede comportarse de manera ligeramente diferente deClassLoader.getResource()
; ver stackoverflow.com/a/676273En Java7 + puede hacer esto en métodos / campos estáticos:
fuente
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Luché con esto yo mismo. Un buen truco es usar el hilo actual para obtener un ClassLoader cuando se encuentre en un contexto estático. Esto también funcionará en un Hadoop MapReduce. Otros métodos funcionan cuando se ejecutan localmente, pero devuelven un InputStream nulo cuando se usa en un MapReduce.
fuente
Simplemente use una clase literal, es decir
NameOfClass.class
fuente
getClass()
El método se define en la clase Object con la siguiente firma:Como no está definido como
static
, no puede llamarlo dentro de un bloque de código estático. Consulte estas respuestas para obtener más información: Q1 , Q2 , Q3 .Si se encuentra en un contexto estático, debe usar la expresión literal de clase para obtener la Clase, por lo que básicamente debe hacer lo siguiente:
Este tipo de expresión se llama Class Literals y se explican en el Java Language Specification Book de la siguiente manera:
También puede encontrar información sobre este tema en la documentación de la API para la Clase.
fuente
Intentalo
O
fuente
[1]
hará que todos los mensajes de registro se informenThread
como su fuente en Android 4.4.4.[2]
parece dar el resultado correcto tanto en Android como en OpenJRE.Supongamos que hay una clase de utilidad, entonces el código de muestra sería:
CustomLocation: si alguna estructura de carpeta dentro de los recursos, de lo contrario, elimine este literal de cadena.
fuente
Intenta algo como esto. Esto funciona para mi. Logg (nombre de clase)
fuente