Pergunta

É possível que o compilador remova instruções usadas para fins de depuração (como registro) do código de produção?As instruções de depuração precisariam ser marcadas de alguma forma, talvez usando anotações.

É fácil definir uma propriedade (debug = true) e verificá-la a cada instrução de depuração, mas isso pode reduzir o desempenho.Seria bom se o compilador simplesmente fizesse as instruções de depuração desaparecerem.

Foi útil?

Solução

Duas recomendações.

Primeiro:para registro real, use um pacote de registro moderno como log4j ou o próprio registro integrado do Java.Não se preocupe tanto com o desempenho, a verificação do nível de registro é da ordem de nanossegundos.(é uma comparação inteira).

E se você tiver mais de uma instrução de log, proteja o bloco inteiro:

(log4j, por exemplo:)

if (logger.isDebugEnabled()) {

  // perform expensive operations
  // build string to log

  logger.debug("....");
}

Isso fornece a capacidade adicional de registrar o controle em tempo de execução.Ter que reiniciar e executar uma compilação de depuração pode ser muito inconveniente.

Segundo:

Você pode encontrar afirmações são mais o que você precisa.Uma afirmação é uma declaração que resulta em um resultado booleano, com uma mensagem opcional:

 assert (sky.state != FALLING) : "The sky is falling!";

Sempre que a asserção resulta em falso, a asserção falha e um AssertionError é lançado contendo sua mensagem (esta é uma exceção não verificada, destinada a sair do aplicativo).

O interessante é que eles são tratados de forma especial pela JVM e podem ser alternados em tempo de execução até o nível de classe, usando um parâmetro VM (sem necessidade de recompilação).Se não estiver ativado, não haverá sobrecarga.

Outras dicas

public abstract class Config
{
    public static final boolean ENABLELOGGING = true;
}

import static Config.*;

public class MyClass
{
    public myMethod()
    {
        System.out.println("Hello, non-logging world");

        if (ENABLELOGGING)
        {
            log("Hello, logging world.");
        }
    }
}

O compilador removerá o bloco de código com "Hello, Logging World". Nele, se o Enable_logging estiver definido como true, porque é um valor final estático.Se você usar um ofuscador como o proguard, a classe Config também desaparecerá.

Um ofuscador também permitiria coisas assim:

public class MyClass
{
    public myMethod()
    {
        System.out.println("Hello, non-logging world");

        Log.log("Hello, logging world.");
    }
}

import static Config.*;

public abstract class Log
{
    public static void log(String s)
    {
        if (ENABLELOGGING)
        {
            log(s);
        }
    }
}

O método Log#log seria reduzido a nada no compilador e seria removido pelo ofuscador, junto com quaisquer chamadas para esse método e, eventualmente, até mesmo a própria classe Log seria removida.

Outra possibilidade é colocar a instrução if dentro da sua função de registro. Dessa forma, você obtém menos código, mas às custas de algumas chamadas de função extras.

Também não sou um grande fã de remover completamente o código de depuração.Quando estiver em produção, você provavelmente precisará de acesso para mensagens de depuração se algo der errado.Se você remover toda a depuração em nível de código, isso não será uma possibilidade.

Usar Pré-processador Java?(google foo low, mas este é um link para os antigos fóruns do Joel discutindo isso)

Java contém algum tipo de pré-processador próprio.É chamado APTO.Ele processa e gera código.No momento não tenho certeza de como isso deve funcionar (não tentei).Mas parece ser usado para esse tipo de coisa.

Eu também recomendo usar uma estrutura de registro.

O logger.IsDebugEnabled() não é obrigatório, apenas pode ser mais rápido verificar se o sistema está no nível de depuração antes de registrar.

Usar uma estrutura de registro em log significa que você pode configurar níveis de registro em tempo real, sem reiniciar o aplicativo.

Você poderia ter registros como:

logger.error("Something bad happened")
logger.debug("Something bad happend with loads more detail")

Esse "truque"parece fazer com que suas instruções de depuração desapareçam

public static final boolean DEBUG = false;

if (DEBUG) { //disapeared on compilation }

O publicar disse isso javac é inteligente o suficiente para verificar o static final boolean e exclua as instruções de depuração.(Eu não tentei pessoalmente)

Para registro, eu pessoalmente não gosto de ver códigos como:

if (logger.isDebugEnabled()) {
    logger.debug("....");
}
realImportantWork();

As coisas de registro me distraem do realImportantWork().O caminho certo para mim é:

logger.debug("....");
realImportantWork()

além da configuração que exclui todas as mensagens de depuração na produção.

Quero dizer que o logger.isDebugEnabled() o controle deve ser trabalho da estrutura de log, não meu trabalho.A maioria das estruturas de registro suportam conceitos como "logger", "LogLevel".o que pode resolver o problema.

Para responder diretamente à sua pergunta:Não sei.

Mas aqui está outra solução para o seu problema:Na minha opinião, há duas afirmações que colidem entre si aqui:"instruções de depuração" e "código de produção".

Qual é o propósito das instruções de depuração?Ajude a se livrar de bugs durante o teste (de unidade).Se um software for devidamente testado e funcionar de acordo com os requisitos, as instruções de depuração nada mais são do que OBSOLETAS.

Discordo veementemente de deixar quaisquer instruções de depuração no código de produção.Aposto que ninguém se preocupa em testar os efeitos colaterais do código de depuração no código de produção.O código provavelmente faz o que deveria fazer, mas faz mais do que isso?Todos os seus #defines funcionam corretamente e realmente eliminam TODO o código de depuração?Quem analisa 100.000 linhas de código pré-processado para ver se todo o material de depuração desapareceu?

A menos que tenhamos uma definição diferente de código de produção, você deve considerar retirar as instruções de depuração depois que o código for testado e terminar com ele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top