Eu tenho uma classe que deve ter alguns métodos estáticos. Dentro desses métodos estáticos, preciso chamar o método getClass () para fazer a seguinte chamada:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
No entanto, o Eclipse me diz:
Cannot make a static reference to the non-static method getClass()
from the type Object
Qual é a maneira apropriada de corrigir esse erro de tempo de compilação?
java
static-methods
Rama
fonte
fonte
getResource()
antes de haver uma instância de uma classe definida pelo usuário (por exemplo, não J2SE) às vezes falha. O problema é que o JRE estará usando o carregador de classes de autoinicialização nesse estágio, que não terá recursos de aplicativos no caminho da classe (do carregador de autoinicialização).Respostas:
A resposta
Basta usar em
TheClassName.class
vez degetClass()
.Declarando registradores
Como isso chama muita atenção para uma base de dados específica - para fornecer uma maneira fácil de inserir declarações de log -, pensei em acrescentar meus pensamentos sobre isso. As estruturas de log geralmente esperam que o log seja restrito a um determinado contexto, digamos um nome de classe totalmente qualificado. Portanto, eles não são passíveis de cópia sem modificação. Sugestões para declarações de log seguras para colar são fornecidas em outras respostas, mas têm desvantagens, como inflar o bytecode ou adicionar a introspecção em tempo de execução. Eu não recomendo estes. Copiar e colar é uma preocupação do editor , portanto, uma solução de editor é mais apropriada.
No IntelliJ, recomendo adicionar um modelo ativo:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
como o texto do modelo.className()
Agora, se você digitar,
log<tab>
ele será expandido automaticamente paraReformate e otimize automaticamente as importações para você.
fonte
Log
no Android, que exige que uma tag seja fornecida, geralmente o nome da classe. E provavelmente existem outros exemplos. Claro que você pode declarar um campo para isso (que é uma prática comum), mas que ainda é copiar e colar.CLASS
digitarclassName()
. Isso garantirá que $ CLASS $ seja realmente substituído pelo nome da classe, caso contrário, ele ficará vazio.Quanto ao exemplo de código na pergunta, a solução padrão é referenciar a classe explicitamente pelo nome, e é até possível sem a
getClassLoader()
chamada:Essa abordagem ainda tem um verso: não é muito seguro contra erros de copiar / colar, caso você precise replicar esse código para várias classes semelhantes.
E quanto à pergunta exata no título, há um truque publicado no segmento adjacente :
Ele usa uma
Object
subclasse anônima aninhada para se apossar do contexto de execução. Esse truque tem a vantagem de ser seguro copiar / colar ...Cuidado ao usar isso em uma Classe Base que outras classes herdam de:
Também é importante notar que, se esse snippet for modelado como um método estático de alguma classe base, o
currentClass
valor sempre será uma referência a essa classe base e não a qualquer subclasse que possa estar usando esse método.fonte
Class.getResource()
pode se comportar um pouco diferente deClassLoader.getResource()
; Veja stackoverflow.com/a/676273No Java7 +, você pode fazer isso em métodos / campos estáticos:
fonte
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Eu lutei com isso sozinho. Um bom truque é usar o thread atual para obter um ClassLoader quando estiver em um contexto estático. Isso funcionará também no Hadoop MapReduce. Outros métodos funcionam ao executar localmente, mas retornam um InputStream nulo quando usado em um MapReduce.
fonte
Basta usar uma classe literal, ou seja,
NameOfClass.class
fonte
getClass()
O método é definido na classe Object com a seguinte assinatura:Como não está definido como
static
, você não pode chamá-lo em um bloco de código estático. Veja estas respostas para obter mais informações: Q1 , Q2 , Q3 .Se você estiver em um contexto estático, precisará usar a expressão literal da classe para obter a classe; portanto, basicamente você deve fazer o seguinte:
Esse tipo de expressão é chamado de Literais de Classe e são explicados no Livro de Especificação de Linguagem Java da seguinte maneira:
Você também pode encontrar informações sobre este assunto na documentação da API para Class.
fonte
Tente
Ou
fonte
[1]
fará com que todas as mensagens de log sejam relatadasThread
como origem no Android 4.4.4.[2]
parece dar o resultado correto no Android e no OpenJRE.Suponha que exista uma classe Utility, o código de exemplo seria -
CustomLocation - se houver alguma estrutura de pastas nos recursos, remova essa literal de cadeia de caracteres.
fonte
Tente algo assim. Funciona para mim. Logg (nome da classe)
fonte