¿Todas las constantes en tiempo de compilación están en línea?
Digamos que tengo una clase 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";
}
Muchas de las otras clases de mi aplicación están usando estas opciones. Ahora, quiero cambiar una de las opciones solo e implementar solo la clase compilada. Pero si estos campos están alineados en las clases de consumidores, esto se vuelve imposible, ¿verdad?
¿Hay alguna opción para deshabilitar el revestimiento interno de las constantes de tiempo de compilación?
6 answers
Puede usar String.intern() para obtener el efecto deseado, pero debe comentar su código, porque no mucha gente sabe acerca de esto. es decir,
public static final String configOption1 = "some option".intern();
Esto evitará el tiempo de compilación en línea. Dado que se refiere a la misma cadena exacta que el compilador colocará en el perm, no está creando nada extra.
Como alternativa, siempre puedes hacer
public static final String configOption1 = "some option".toString();
Sin embargo esto no usará la cadena interna compilada, creará una nueva en la vieja generación. gran gran cosa, y podría ser más fácil de leer. De cualquier manera, ya que esto es un poco extraño, debe comentar el código para informar a los que lo mantienen lo que está haciendo.
Editar: Encontramos otro enlace SO que da referencias a la JLS, para más información sobre esto. Cuándo usar intern () en literales de cadena
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:30:47
No, es parte de la JLS, me temo. Esto se toca, brevemente, en los Puzzles de Java, pero no tengo mi copia a mano.
Supongo que podría considerar tener estas constantes definidas en un archivo de propiedades, y tener la clase que las carga periódicamente.
Referencia: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 13:23:03
No. Sin embargo, podría reemplazarlos con una llamada a un método estático, como:
class ApplicationDefs {
public static String configOption1() { return "some option"; }
}
Concedido, no es hermoso pero cumpliría su requisito. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 13:24:34
En realidad, si elimina la palabra clave final
las constantes dejan de ser constantes en tiempo de compilación y entonces su configuración funcionará como desee.
Sin embargo, se sugiere fuertemente que si esto es de hecho algún tipo de configuración que está tratando de hacer, debe moverse a una forma más manejable que las constantes en algún archivo de clase.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 13:46:11
Puede inhibir la inserción haciendo que sus constantes no sean constantes de tiempo de compilación...
Por ejemplo, null
no es una constante de tiempo de compilación. Cualquier expresión que involucre una constante de tiempo de compilación no es una constante de tiempo de compilación, aunque javac puede hacer plegamiento constante dentro de la unidad de compilación.
public static final String configOption1 = null!=null?"": "some option";
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 15:04:57
No hay nada aquí que diga que estos valores deben estar en línea. Usted está declarando algunos public
, static
miembros. Esas otras clases están usando los valores de estos miembros. No se pide ninguna entrada. Incluso la palabra clave final
Pero por razones de rendimiento , algunas JVM pueden inline estos valores en esas otras clases. Esto es una optimización. Ninguna optimización debería cambiar el comportamiento de un programa. Así que si cambias la definición de estos miembros, la JVM debería des-inline los valores anteriores.
Esta es la razón por la que no hay manera de desactivar la inserción. O bien la JVM no está en línea y no hay ningún problema o si está en línea, la JVM garantiza que no esté en línea.
No estoy seguro de lo que sucede cuando se importa estáticamente esta clase. Creo (no estoy seguro) que la inserción se realiza y puede causar los problemas que mencionas. Si ese es el caso, básicamente podría eliminar la importación estática y está bien.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 13:38:46