Todas as constantes de tempo de compilação estão inlinadas?
-
22-08-2019 - |
Pergunta
Digamos que eu tenho uma aula como esta:
class ApplicationDefs{
public static final String configOption1 = "some option";
public static final String configOption2 = "some other option";
public static final String configOption3 = "yet another option";
}
Muitas das outras classes do meu aplicativo estão usando essas opções. Agora, quero alterar uma das opções sozinha e implantar apenas a classe compilada. Mas se esses campos estiverem envolvidos nas classes de consumo, isso se torna impossível, certo?
Existe alguma opção para desativar a atualização de constantes de tempo de compilação?
Solução
Você pode usar o string.intern () para obter o efeito desejado, mas deve comentar seu código, porque poucas pessoas sabem disso. ou seja
public static final String configOption1 = "some option".intern();
Isso impedirá o tempo de compilação em linha. Como está se referindo à mesma string que o compilador colocará no PERM, você não está criando nada extra.
Como alternativa, você sempre pode fazer
public static final String configOption1 = "some option".toString();
No entanto, isso não usará a string estagiária compilada, ele criará uma nova na geração antiga. Não é um grande negócio e pode ser mais fácil de ler. De qualquer maneira, como isso é um pouco estranho, você deve comentar o código para informar aqueles que o mantêm o que está fazendo.
Editar:Encontrei outro link SO que fornece referências ao JLS, para obter mais informações sobre isso.Quando usar o Intern () em literais de cordas
Outras dicas
Não, faz parte do JLS, tenho medo. Isso é tocado, brevemente, nos quebra -cabeças de Java, mas não tenho minha cópia em mãos.
Acho que você pode considerar definir essas constantes em um arquivo de propriedades e ter a classe que as carrega periodicamente.
Referência: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
Não. Você pode substituí -los por uma chamada de método estático, porém, como:
class ApplicationDefs {
public static String configOption1() { return "some option"; }
}
É verdade que não é bonito, mas cumpriria sua exigência. :)
Na verdade, se você remova o final
palavra -chave As constantes deixam de ser constantes de tempo de compilação e depois sua configuração vai funcionar como você quer.
No entanto, é fortemente sugerido que, se esse é realmente algum tipo de configuração que você está tentando fazer, você deve passar para uma maneira mais gerenciável do que as constantes em algum arquivo de classe.
Você pode inibir a inline fazendo suas constantes constantes de tempo não-compilantes ...
Por exemplo, null
não é um tempo de compilação constante. Qualquer expressão que envolve uma constante de tempo não compilador não seja uma constante de tempo de compilação, embora o JAVAC possa fazer dobragem constante dentro da unidade de compilação.
public static final String configOption1 = null!=null?"": "some option";
Não há nada aqui que diga que esses valores devem ser inlinados. Você está apenas declarando alguns public
, static
membros. Essas outras classes estão usando os valores desses membros. Nenhuma inline é perguntada. Mesmo o final
palavra -chave
Mas pelo razões de desempenho, algumas JVMs podem em linha Esses valores nessas outras classes. Esta é uma otimização. Nenhuma otimização deve mudar o comportamento de um programa. Então, se você mudar a definição desses membros, a JVM deve un-in-inline os valores anteriores.
É por isso que não há como desligar. Ou a JVM não é embutida e não há problema ou, se estiver inlinada, a JVM garante a desinlação.
Não tenho certeza do que acontece quando você importa estaticamente nesta classe. Eu acho (não tenho certeza), o envolvimento é realizado e pode causar o problema que você menciona. Se for esse o caso, você pode basicamente excluir a importação estática e está bem.