2010-10-16 10 views
8

Analicé el código en el que estoy trabajando utilizando un analizador de código fuente Java. Una de las advertencias es "Declarar siempre excepciones definidas por el usuario como definitivas". Hay muchas otras advertencias que no tienen mucho sentido, pero esta me hizo un poco confundido.¿Por qué? "Declarar siempre excepciones definidas por el usuario como definitivas"

Estoy trabajando en un marco y tengo una excepción genérica de raíz (por ejemplo, FrameworkGenericException) y para otras excepciones, simplemente los derivo de la excepción raíz. Entonces tengo una jerarquía de excepciones para el marco. Podría extender la jerarquía, pero creo que esta advertencia me dice que no tengo dicha jerarquía, sino que las defino individualmente. Entonces, ¿qué camino debo tomar, cuáles son tus comentarios?

+8

Me uno a tu confusión, esta sugerencia no parece tener mucho sentido. –

+0

+1 para "WTF?" ... – SimonJ

+1

¿cuál es el analizador de código fuente? ¿Está generalmente disponible para otros? – msw

Respuesta

4

Esto es probablemente una práctica estándar para ellos: declarar las clases como definitivas si se supone que no deben heredarse, y también probablemente piensen que no se extenderán todas sus excepciones.

Sin embargo, en su caso, creo que es una buena idea hacer una excepción genérica y ampliar todas las demás. Por ejemplo, usted tiene:

public void frameworkMethod() throws IllegalDataException, InvalidCommandException; 

donde estas excepciones son sublasses de FrameworkException. Entonces podrías manejar las excepciones un poco más fácilmente.

try { 
    frameworkMethod(); 
} catch (FrameworkException ex) { 
    logger.log(Level.SEVERE, "An exception occured!", ex); 

    if (ex instanceof IllegalDataException) { 
     // Do something to recover 
    } else if (ex instanceof InvalidCommandException) { 
     //Inform the user 
    } //And so on... 
} 

Así que yo diría que está haciendo lo correcto, será más fácil trabajar con la arquitectura de su programa.

+0

@Malcom Esto es exactamente lo que estoy haciendo ...Y solo en algunos casos hay ese tipo de if/else – erdogany

+0

Sí, pensé que sería mejor ilustrar por qué puede ser conveniente tener un árbol de excepciones y no solo una excepción por cada caso muy especial. – Malcolm

+0

Muy común tener una excepción OurDomainException para permitir una fácil clasificación. –

2

Nunca he oído hablar de esta recomendación, ni tiene ningún sentido para mí.

¿Qué herramienta está utilizando? Intenté buscar en Google ese mensaje y obtuve ZERO hits aparte de su pregunta SO. Probar otras búsquedas para intentar "explotar la sabiduría de la red" tampoco me dio nada obviamente relevante.

tal vez debería pedir a los autores herramienta de análisis de código para explicar la razón de esta regla de estilo ...

+0

Sí ... Ok, si no sale nada, haré eso y les haré saber a ustedes;) Pero deberíamos hacer una lluvia de ideas antes de preguntar ... – erdogany

2

extraño. Google muestra solo un documento con esas palabras: su pregunta :)

En mis proyectos, esto es bastante normal tener ancestros definidos por el usuario para todas las excepciones. Pocos años de desarrollo en este estilo, nada especial hasta ahora vinculado a eso.

2

El hecho es que una herramienta de análisis estático básicamente escanea su código por violaciones de (lo que el autor de la herramienta considera) "mejores prácticas". En este caso, generalmente se considera una "mejor práctica" tener jerarquías de excepciones muy superficiales.

La razón es que básicamente hay dos oportunidades en las que detectará una excepción. El primero es si desea detectar la excepción porque sabe cómo manejarlo. Por ejemplo:

try 
{ 
    return fetchDataFromFile(); 
} 
catch(FileNotFoundException) 
{ 
    return defaultData; 
} 

En este caso, usted cogió el FileNotFoundException porque quiere volver "datos por defecto" cuando no se encuentra el archivo. En esta situación, normalmente detecta una clase de excepción específica - porque ese es el único tipo de excepción que sabe cómo manejar (por ejemplo, si fetchDataFromFile arroja alguna otra excepción, no desea que devuelva datos predeterminados.

la otra vez que va a coger excepciones está en la raíz misma de su hilo,

try 
{ 
    doStuff(); 
catch(Exception e) 
{ 
    logException(e); 
    notifyUser(e); 
} 

en este caso, usted coge la clase de excepción de la raíz, ya que desea específicamente todas las excepciones para que pueda conectarse ellos, o notificar al usuario.

Hay muy pocas situaciones en las que necesite hacer algo más.

Ahora, recuerde que esta es una herramienta de análisis estático. Su trabajo es simplemente señalarle problemas "potenciales". Si cree que su situación es de alguna manera diferente, entonces la idea es documentar por qué cree que es diferente y específicamente desactivar esa advertencia para esa sección de código (o esa clase o lo que sea).

+1

si eso es lo que están tratando de hacer, lo están haciendo mal camino. Además, creo que el verdadero problema es que no debes ser flojo y declarar todo como arrojar la excepción de la raíz. OMI, la profundidad de la jerarquía es inmaterial. –

+0

Motivo de FrameworkGenericException, por ejemplo: SQLException (supongamos que algunas excepciones específicas provienen de API subyacentes que no pueden recuperarse). Entonces esta excepción específica está blindada. Los clientes de este marco no necesitan saber acerca de la excepción específica, sino que obtienen FrameworkGenericException como una excepción que no hay nada que hacer. Pero si obtienen SomethingNotFound extiende FrameworkGenericException se vuelve significativo. Y las excepciones BTW solo tienen dos niveles de derivación. – erdogany

+0

Creo que no hay nada de malo en crear una jerarquía de excepciones, esto hace que el programa sea más fácil de entender y trabajar. Ver mi respuesta, he proporcionado un ejemplo para esto. – Malcolm

2

Apuesto a que ese mensaje desaparece si hace su resumen genérico de excepción. Seguirás a otro respetado gurú orientado a objetos, Scott Meyer:

Haz que las clases que no sean hojas sean abstractas.

Personalmente, no estoy de acuerdo con una excepción de raíz para todo el marco. ¿Qué comportamiento extraordinario ha incorporado en él que todos los niños heredarán más de lo que viene de java.lang.Throwable?

Creo que tener SpecialBusinessException anulando los cuatro constructores desde java.lang.RuntimeException es suficiente. ¿Cuál es el punto de la jerarquía? Apuesto a que es plano y ancho, con una clase raíz. ¿Por qué molestarse?

+0

¿Permitir que la captura de nivel superior identifique claramente si esta es una excepción de proveedor o no? –

+0

Creo que el nombre del paquete del proveedor debería ser suficiente. ¿Cuánta más indicación necesitas? – duffymo

Cuestiones relacionadas