2012-09-24 17 views
7

gente,Java - Clone la propiedad dentro de método getter

yo estaba pasando por mejores prácticas de codificación de Java mencionados aquí
http://viralpatel.net/blogs/most-useful-java-best-practice-quotes-java-developers/

segunda cita dice,

Cita 2: Nunca hacer una campos de instancia de clase pública

Estoy de acuerdo que es absolutamente correcto, pero me quedé atrapado por seguir la recomendación del escritor pocas líneas debajo de esta cita.

Dice,


private String[] weekdays = 
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() { 
    return weekdays; 
} 

Pero escribir método getter no resuelve nuestro problema exactamente. La matriz sigue siendo accesible. La mejor manera de hacerlo no modificable es devolver un clon de matriz en lugar de la matriz misma. Así, el método de obtención se cambiará a

public String[] getWeekdays() { 
    return weekdays.clone(); 
} 

he utilizado nunca me clone() dentro de cualquier método de obtención de la clase Java.

Me pregunto (como se menciona a ser una de las buenas prácticas) - por qué uno should use/shouldn't useclone() dentro método getter? y en que escenarios?

¿Califica para ser una buena práctica de codificación para Java?

Gracias

+2

IMO: para objetos inmutables y tipos de datos primitivos, no es necesario clonar. Para todo lo demás, si realmente queremos que nuestros datos estén seguros, debemos devolver la copia clonada y no la original. –

+2

Puede devolver 'Arrays.asList (entre semana)', que será inmutable. – Jivings

+2

@Jivings no es cierto. La Lista no aceptará nuevos elementos, pero los métodos set() funcionan. –

Respuesta

3
private String[] weekdays =  
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() 
{  
    return weekdays; 
} 

Si no se utiliza clone método, el usuario de esta clase puede hacer un montón de cosas poco éticas:

  1. cambio del orden del día,
  2. cambio el nombre de días,
  3. ...

Pero devolver un clon no afectará la clase y sus datos. Entonces, otros usuarios de clase no se verán afectados.

+0

Pero no vi la recomendación del método clone() en ningún sitio web anteriormente. No vi a la mayoría de los programadores (incluso algunos geeks de Java) usar eso en sus ejemplos. Dudo, si esa es una buena práctica de codificación, entonces? : O –

+0

@bomslang Mucho bajará sus requisitos. Como ha señalado Azodious, no clonar (probar cualquier otra copia de los datos) puede provocar problemas inesperados para su clase, pero debe decidir si este es el comportamiento que desea. La razón por la que probablemente no lo ve es porque es más tipeo para la mayoría de las personas. Si echa un vistazo a la API de Swing, verá muchas prácticas simulares, cuando devuelva 'Dimension', la clase a menudo creará un nuevo objeto' Dimension', usando su referencia interna como la semilla de esa nueva clase, esencialmente, clonándolo – MadProgrammer

+2

Sí, lo es. y personalmente lo he usado en un caso casi similar a tu ejemplo. Pero no debe usarse a ciegas porque si se clona un objeto pesado, provocará problemas de memoria. Por lo tanto, clone solo los datos que un usuario no debe modificar. – Azodious

2

Usted clone() or System.arraycopy() en get() si desea garantizar que el gráfico de objeto completo (que contiene la matriz) es inmutable. Esto se hace generalmente cuando la API que expone la matriz es public y hay restricciones en los valores de la matriz o cuando se accede a los objetos por múltiples hilos. En tales casos, la inmutabilidad es importante.

Supongamos que tiene un objeto GroceryStore que tiene el método getItemsSortedByPrice(). Mantiene los artículos en una matriz que mantiene el orden por precio, pero si devuelve esta matriz, el código del cliente posiblemente puede modificarla y romper las invariantes (internas) de su objeto.

Si se trata de un código interno (es decir) que no forma parte de la API pública, y sabe que no modificará la matriz, la clonación probablemente no sea necesaria, ya que perjudica el rendimiento sin beneficio real.

Todo depende del contexto.

Las matrices son solo objetos, y todas las reglas/prácticas de (im) mutabilidad que se aplican a un objeto ordinario, se aplican también a las matrices.

+1

+1 for System.arrayCopy (), aunque recomendaría la versión más útil Arrays.copyOf() (que por supuesto usa System.arrayCopy() internamente) –

1

Creo que su uso no coincide con el código Java propuesto. El ejemplo es para un caso de uso diferente al tuyo.

Una matriz final me suena como Enums y creo que esto se adapta mucho mejor a sus necesidades.

5

Esto se discute en el libro "Effective Java" por Joshua Bloch. Hay una sección llamada "Haga copias defensivas cuando sea necesario" (Sección 39 en la 2da edición).

Creo que los libros de Google podrían permitirle ver una vista previa de la sección.

Un buen libro para hablar sobre temas como este.

Cuestiones relacionadas