tengo este codigo:
public static class MyWebDriver extends RemoteWebDriver { @NotNull private final String nodeId; public MyRemoteWebDriver(@NotNull String nodeId) { super(); this.nodeId = nodeId; } @Override public void quit() { System.out.println("deleting node: " + nodeId); } } y se garantiza que nodeId que se pasa al constructor no es null . Y debido a que el campo nodeId es final , espero que se inicialice en mi método quit() .
Pero, en el constructor super() hay un bloque try-catch que, en caso de excepción, llama al método quit() y lanza una excepción . Y en este caso, nodeId que obtengo en mi método quit() no se inicializa (tiene un valor null ).
¿Hay alguna forma de evitarlo excepto
@Override public void quit() { if (nodeId != null) { System.out.println("deleting node: " + nodeId); } } ¿Éste? Lo que parece bastante estúpido, porque nodeId está marcado como @NotNull .
Pero, en el constructor super() hay un bloque try-catch que en caso de excepción llama a quit()
Son dos problemas en uno:
los constructores no deben hacer ningún trabajo excepto almacenar los parámetros dados en las variables miembro ( final ).
[editar]
¿Significa eso que las clases no deberían validar sus entradas? Conozco a muchas personas que no estarían de acuerdo con que todos sus objetos posiblemente no sean válidos en lugar de que nunca existan. - chris
Por "no debería hacer ningún trabajo" quiero decir que el constructor no debe calcular ningún valor de propiedad de los parámetros o llamar a una dependencia o un método no público para realizar la verificación.
los constructores nunca deben llamar a ningún método que no sea private y/o final (dentro de la clase), ya sea directa o indirectamente (es decir, no debe llamar a un método final que a su vez invoque un método no final ).
La razón por la que te encuentras con este problema es la violación del Patrón de responsabilidad única y la Separación de preocupaciones .
Lo que sea que haga en el constructor de superclases probablemente debería hacerse en una clase separada y solo los resultados de ese proceso deberían pasarse a su clase (y su superclase).
Obviamente, esto significa que el método quit() también pertenece a una clase diferente.
Por supuesto, esto se explica fácilmente por el hecho de cómo funciona Java. Un objeto de tipo MyWebDriver no se inicializa, incluidos sus campos, es decir, incluye en su caso nodeId hasta que se inicializan sus campos heredados de la superclase, es decir, en su caso, hasta que vuelve super() .
Entonces, si se lanza una excepción en super , claramente nodeId será null .
No creo que haya ninguna solución (excepto algunas similares a las que sugiere) a menos que el marco que está utilizando (que no especificó) proporcione alguna solución.
Puede mover la lógica de inicialización del superconstructor al método init() protegido e invocarlo después de la inicialización de nodeId.
Tal vez se pueda usar un diseño más claro aquí, pero es difícil sugerir algo sin un ejemplo completo.