2009-02-23 18 views
5

¿Por qué se ve lo siguiente como mejor que la forma antigua de fundición?Java genéricos

MyObj obj = someService.find(MyObj.class, "someId");

vs

MyObj obj = (MyObj) someService.find("someId");

+1

Quién dice que esto es mejor? – Milhous

Respuesta

4

Otra ventaja del uso de un parámetro de tipo explícito sería permitir que el método de servicio se implemente utilizando un Proxy (en este caso MyObj debería ser MyInterface). Sin parámetros de tipo explícitos, esto no sería posible.

Es posible utilizar un Proxy bajo las sábanas por muchas razones (Pruebas de uno)

9

No hay garantía de que la versión no genéricos devolverá un objeto de tipo 'MyObj', por lo que podría conseguir un ClassCastException.

6

En el caso 1, la mayoría de los servicios bien implementados podrían devolver nulos si no se puede encontrar ningún objeto con id someId de tipo MyObj. Además, el primer caso hace posible que el servicio tenga cierta lógica específica particular para trabajar con clases del tipo MyObj.

En el caso 2, a menos que use instanceof (evite si es posible), entonces se está arriesgando a un feo ClassCastException que debería atrapar y manejar.

3

Una razón por la cual el primer escenario es mejor es que el método find(Class,String) ahora tiene conocimiento de a qué se le está asignando el valor de retorno. Por lo tanto, ahora es capaz de realizar conversiones relevantes internamente en lugar de simplemente esperar que se devuelva el tipo correcto. Por ejemplo, supongamos que el método find localiza un objeto String internamente cuando se lo llama con "someId". El método find puede tener una estrategia para convertir un String en una instancia MyObj.

0

No es mejor. Podría decirse que es peor, excepto en circunstancias muy específicas. El único momento en que necesita ese tipo de cosas es cuando el objetivo necesitará llamar a newInstance() (etc) en el objeto de clase: métodos de fábrica y demás.

Si desea guardar los electrones, por cierto, esto también trabajar

MyObj obj = someService.find((Class<MyObj>) null, "someId");