¿Cuál es la razón de estas reglas de PMD?
Pregunta
DataflowAnomalyAnalysis: encontrado Anomalía 'DD' para variable 'variable' (líneas 'n1' - 'n2').
DataflowAnomalyAnalysis: encontrado Anomalía 'DU' para variable 'variable' (líneas 'n1' - 'n2').
DD y DU suenan familiares ... Quiero decir en cosas como pruebas y análisis relacionados con las condiciones pre y post más débiles, pero no recuerdo los detalles.
NullAssignment: asignación de un objeto a nulo es un código de olor. Considerar refactorización.
¿No establecer un objeto en null
ayudaría en la recolección de basura, si el objeto es un objeto local (no se usa fuera del método)? ¿O es eso un mito?
MethodArgumentCouldBeFinal: Parámetro 'param' no está asignado y podría ser declarado final
LocalVariableCouldBeFinal: Local variable 'variable' podría ser declarada final
¿Hay alguna ventaja en usar los parámetros y variables final
?
Acoplamiento suelto: evite usar tipos de implementación como 'Lista enlazada'; usa la interfaz en su lugar
Si sé que necesito específicamente una LinkedList
, ¿por qué no usaría una para dejar mis intenciones explícitamente claras a futuros desarrolladores? Una cosa es devolver la clase que está más arriba en la ruta de la clase que tiene sentido, pero ¿por qué no declararía que mis variables tienen el sentido más estricto?
EviteSynchronizedAtMethodLevel: Use nivel de bloque en lugar de nivel de método sincronización
¿Qué ventajas tiene la sincronización a nivel de bloque sobre la sincronización a nivel de método?
Evite el uso de ShortType: no utilice el tipo corto
Mis primeros lenguajes fueron C y C ++, pero en el mundo Java, ¿por qué no debería usar el tipo que mejor describe mis datos?
Solución
-
Las anomalías DD y DU (si no recuerdo mal, uso FindBugs y los mensajes son un poco diferentes) se refieren a la asignación de un valor a una variable local que nunca se lee, generalmente porque se le ha reasignado otro valor antes que nunca siendo leído Un caso típico sería inicializar alguna variable con
null
cuando se declara. No declare la variable hasta que sea necesaria. -
Asignación de
null
a una variable local para " ayudar " El recolector de basura es un mito. PMD le permite saber que esto es solo un desorden contraproducente. -
Especificar final en una variable local debería ser muy útil para un optimizador, pero no tengo ningún ejemplo concreto de JIT actuales que aprovechen esta sugerencia. Lo he encontrado útil para razonar sobre la corrección de mi propio código.
-
Especificar interfaces en términos de ... bueno, interfaces es una gran práctica de diseño. Puede cambiar fácilmente las implementaciones de la colección sin afectar a la persona que llama. De eso se tratan las interfaces.
-
No puedo pensar en muchos casos en los que una persona que llama requiere una
LinkedList
, ya que no expone ninguna API que no haya sido declarada por alguna interfaz Si el cliente confía en esa API, está disponible a través de la interfaz correcta. -
La sincronización a nivel de bloque permite que la sección crítica sea más pequeña, lo que permite que se realice la mayor cantidad de trabajo simultáneo posible. Quizás lo más importante es que permite el uso de un objeto de bloqueo controlado de forma privada por el objeto que lo encierra. De esta manera, puede garantizar que no se produzca un punto muerto. Al usar la instancia en sí como un bloqueo, cualquiera puede sincronizarla incorrectamente, causando un punto muerto.
-
Los operandos de tipo
short
se promocionan aint
en cualquier operación. Esta regla le permite saber que esta promoción está ocurriendo, y también podría usar unint
. Sin embargo, usar el tiposhort
puede ahorrar memoria, por lo que si es un miembro de instancia, probablemente ignore esa regla.
Otros consejos
DataflowAnomalyAnalysis: encontrado Anomalía 'DD' para variable 'variable' (líneas 'n1' - 'n2').
DataflowAnomalyAnalysis: encontrado Anomalía 'DU' para variable 'variable' (líneas 'n1' - 'n2').
No tengo idea.
NullAssignment: asignación de un objeto a nulo es un código de olor. Considerar refactorización.
¿No establecer un objeto en
null
ayudaría en la recolección de basura, si el objeto es un objeto local (no se usa fuera del método)? ¿O es eso un mito?
Los objetos en los métodos locales se marcan como basura recolectada una vez que el método regresa. Establecerlos en nulo no hará ninguna diferencia.
Dado que haría que los desarrolladores tuvieran menos experiencia, ¿qué es esa asignación nula? Puede considerarse un olor a código.
MethodArgumentCouldBeFinal: Parámetro 'param' no está asignado y podría ser declarado final
LocalVariableCouldBeFinal: Local variable 'variable' podría ser declarada final
¿Hay alguna ventaja en usar los parámetros y variables
final
?
Aclara que el valor no cambiará durante el ciclo de vida del objeto.
Además, si por casualidad alguien intenta asignar un valor, el compilador evitará este error de codificación en el tipo de compilación.
considera esto:
public void businessRule( SomeImportantArgument important ) {
if( important.xyz() ){
doXyz();
}
// some fuzzy logic here
important = new NotSoImportant();
// add for/if's/while etc
if( important.abc() ){ // <-- bug
burnTheHouse();
}
}
Suponga que está asignado a resolver algún error misterioso que de vez en cuando quema la casa.
Usted sabe cuál fue el parámetro utilizado, lo que no entiende es POR QUÉ se invoca el método burnTHeHouse
si no se cumplen las condiciones (según sus hallazgos)
Le tomará un tiempo descubrir que en algún punto en el medio, alguien cambia la referencia, y que está utilizando el objeto otro .
El uso de final
ayuda a prevenir este tipo de cosas.
Acoplamiento suelto: evite usar tipos de implementación como 'Lista enlazada'; usa la interfaz en su lugar
Si sé que necesito específicamente una
LinkedList
, ¿por qué no usaría una para dejar mis intenciones explícitamente claras para futuros desarrolladores? Una cosa es devolver la clase que está más arriba en la ruta de la clase que tiene sentido, pero ¿por qué no declararía que mis variables tienen el sentido más estricto?
No hay diferencia, en este caso. Creo que, dado que no está utilizando la funcionalidad específica de LinkedList
, la sugerencia es justa.
Hoy, LinkedList podría tener sentido, pero al usar una interfaz te ayudas a ti mismo (o a otros) a cambiarlo fácilmente cuando no sea así.
Para proyectos pequeños y personales, esto puede no tener sentido en absoluto, pero dado que ya está utilizando un analizador, supongo que ya le importa la calidad del código.
Además, ayuda a los desarrolladores menos experimentados a crear buenos hábitos. [No digo que seas uno pero el analizador no te conoce;)]
EviteSynchronizedAtMethodLevel: Use nivel de bloque en lugar de nivel de método sincronización
¿Qué ventajas tiene la sincronización a nivel de bloque sobre la sincronización a nivel de método?
Cuanto más pequeña sea la sección sincronizada, mejor. Eso es todo.
Además, si sincroniza a nivel de método, bloqueará todo el objeto. Cuando sincroniza a nivel de bloque, simplemente sincroniza esa sección específica, en algunas situaciones eso es lo que necesita.
Evite el uso de ShortType: no utilice el tipo corto
Mis primeros lenguajes fueron C y C ++, pero en el mundo de Java, ¿por qué no debería usar el tipo que mejor describe mis datos?
Nunca he oído hablar de esto, y estoy de acuerdo contigo :) Sin embargo, nunca uso short.
Supongo que al no usarlo, se estará ayudando a sí mismo a actualizarse a int
sin problemas.
Los olores de código están más orientados a la calidad del código que las optimizaciones de rendimiento. Por lo tanto, se dan consejos para programadores con menos experiencia y para evitar dificultades, que para mejorar la velocidad del programa.
De esta manera, podría ahorrar mucho tiempo y frustraciones al intentar cambiar el código para que se ajuste a un mejor diseño.
Si el consejo no tiene sentido, simplemente ignórelos, recuerde, usted es el desarrollador a cargo y la herramienta es solo una herramienta. Si algo sale mal, no puedes culpar a la herramienta, ¿verdad?
Solo una nota sobre la pregunta final
.
Poner " final " en una variable solo se puede asignar una vez . Esto no significa necesariamente que sea más fácil de escribir, pero ciertamente significa que es más fácil leer para un futuro mantenedor.
Tenga en cuenta estos puntos:
- cualquier variable con un
final
puede clasificarse inmediatamente en " no cambiará el valor mientras se ve " ;. - por implicación significa que si todas las variables que no cambiarán están marcadas con final, entonces las variables que NO están marcadas con final REALMENTE cambiarán.
Esto significa que al leer la parte de definición ya puede ver qué variables debe tener en cuenta, ya que pueden cambiar el valor durante el código, y el responsable puede dedicar sus esfuerzos mejor ya que el código es más legible.
No establecería un objeto como nulo ayudar en la recolección de basura, si el objeto es un objeto local (no utilizado fuera del método)? ¿O es eso un mito?
Lo único que hace es hacer posible que el objeto sea GCd antes del final del método, lo que rara vez es necesario.
¿Hay alguna ventaja en usar parámetros y variables finales?
Hace que el código sea algo más claro, ya que no tiene que preocuparse por el cambio del valor en algún lugar cuando analiza el código. Más a menudo, entonces no necesita o no desea cambiar el valor de una variable una vez que se establece de todos modos.
Si sé que necesito específicamente un LinkedList, ¿por qué no usaría una para dejar mis intenciones explícitamente claras para futuros desarrolladores?
¿Puedes pensar en alguna razón por la que específicamente necesitarías un LinkedList?
Una cosa es devolver la clase que está más arriba camino de clase que tiene sentido, pero ¿por qué? ¿No declararía que mis variables son del sentido más estricto?
No me importan mucho las variables o campos locales, pero si declaras un parámetro de método de tipo LinkedList
, te buscaré y lastimaré, porque me hace imposible use cosas como Arrays.asList ()
y Collections.emptyList ()
.
¿Qué ventajas tiene la sincronización a nivel de bloque sobre la sincronización a nivel de método?
El más importante es que le permite usar un objeto de monitor dedicado para que solo esas secciones críticas sean mutuamente excluyentes que deben ser, en lugar de todo lo que use el mismo monitor.
en el mundo Java, ¿por qué no debería usa el tipo que mejor describe mi datos?
Debido a que los tipos más pequeños que int se promueven automáticamente a int para todos los cálculos y hay que rechazarlos para asignarles cualquier cosa. Esto lleva a un código desordenado y mucha confusión (especialmente cuando se trata de autoboxing).
EviteUsarShortType: no utilice el tipo corto
-
Elemento de la lista
corto es de 16 bits, el cumplido de 2 en Java
- una operación matemática corta con cualquier elemento de la familia Integer fuera de otro corto requerirá una conversión de extensión de signo de tiempo de ejecución al tamaño más grande. operar contra un punto flotante requiere una extensión de signo y una conversión no trivial a IEEE-754.
- no puede encontrar pruebas, pero con un registro de 32 bits o 64 bits, ya no está ahorrando en 'instrucciones de procesador' a nivel de código de bytes. Está estacionando un automóvil compacto en el lugar de estacionamiento de un semirremolque en lo que respecta al registro del procesador.
- Si está optimizando su proyecto a nivel de código de bytes, wow. simplemente guau. ; P
- Estoy de acuerdo con el lado del diseño de ignorar esta advertencia pmd, solo ponderar con precisión la descripción de su objeto con un 'corto' frente a las conversiones de rendimiento incurrido.
- en mi opinión, los resultados de rendimiento incurridos son minúsculos en la mayoría de las máquinas. ignorar el error.
¿Qué ventajas tiene el nivel de bloque sincronización tiene más de nivel de método ¿sincronización? Sincronizar un método es como hacer un bloque
synchronize (getClass ())
y bloquea toda la clase.
Quizás no quieras eso