Pregunta

características de Java realmente admiro y no quieren renunciar a usarlo para el siguiente problema:

Tengo una clase que podría ser heredado, y en el interior de la misma es un private ArrayList arr; Por lo tanto la función de colocador está bien, pero el return arr; función getter devuelve la referencia a esa variable que cualquiera capaz de editar toda esa matriz que no lo hago quieren y privada no tendría ningún sentido!

En C ++ lo haría solo return const arr; y volvería referencia constante a la variable.

Me necesita tanto la variable no se va a clonar o copiar manualmente porque hay tantos cálculos que requieren (sólo lectura de la variable) por qué no hay const regresando en Java ???? ¿hay alguna manera de que pudiera escapar de la copia?

(final ArrayList<Integer> arr;) p.s no es una opción causa que array siempre cambia valores de tamaño o elemento.

Si no pude encontrar una solución a la que estoy amenazando con volver a C ++ o todo público marca y nunca se debe obtener el software: D


EDIT: una pregunta más importante: ¿Estoy pidiendo algo que no es bueno (Ingeniería del software en cuanto a) Es decir, si los creadores de JAVA idea de no tener referencia constante (volviendo Leer únicas referencias) entonces debo estar pidiendo algo que puede ser manejado de otra manera. o mi diseño del programa está mal Estoy tan confundido.

¿Fue útil?

Solución

Envolver el valor de retorno con java.util.Collections.unmodifiableList . No hace una copia de los datos, sino que envuelve la lista original, y los delegados a las operaciones de la lista subyacente de sólo lectura. Las operaciones que modifiquen la lista son rechazados en tiempo de ejecución a través de UnsupportedOperationException.

return arrayList;

se convierte

return Collections.unmodifiableList(arrayList);

Por desgracia, las limitaciones de sólo lectura no se hace cumplir por el compilador. Ellos, sin embargo, hacerse cumplir en tiempo de ejecución.

También tiene a su disposición: unmodifiableSet , unmodifiableMap , unmodifiableCollection , unmodifiableSortedSet y unmodifiableSortedMap . Y si esto no es suficiente, todavía puede tomar la inspiración de este enfoque de diseño general y crear su propia costumbre de sólo lectura envoltorio clases.

Otros consejos

:) Usted tiene varias opciones:

  • No exponga captador, proporcionar sólo los métodos que se permite a la llamada, por ejemplo.

    public void addToList(Object arg) { this.arr.add(arg);}

  • Vuelta objeto inmutable:

    public List getArr() { return Collections.unmodifiableList(this.arr); }

También podría usar Google guayaba 's inmutable colecciones . En este caso, se debe almacenar un ImmutableList en su campo.

Por supuesto, si sus necesidades de clase para modificar esta lista internamente, utilizando ImmutableList podría llegar a ser una mala idea, ya que necesitará para crear una nueva instancia ImmutableList y reasigna a la campo cada vez ...

Pero es perfecta cuando se conoce la lista no va a cambiar después de la construcción de objetos.

ejemplo Immutable (lista no va a cambiar después de la construcción objeto)

@Immutable
public final class Foo {

    @Nonnull
    private final ImmutableList<String> list;

    public Foo(@Nonnull List<String> list) {
        // you could also compute the appropriate list here
        // before assigning it to the field
        this.list = ImmutableList.copyOf(list);
    }


    public ImmutableList<String> getList() {
        return list;
    }
}

ejemplo Mutable (lista sólo puede ser modificado utilizando el setter)

public class Foo {

    @Nonnull
    private ImmutableList<String> list = ImmutableList.of();

    public ImmutableList<String> getList() {
        return list;
    }

    public void setList(@Nonnull List<String> list) {
        this.list = ImmutableList.copyOf(list);
    }
}

Observaciones

  • Sé que a menudo se aconseja a los métodos devolverlo es el tipo genérico más posible (List en este caso), pero yo prefiero que declarar el tipo de devolución de mi getter como ImmutableList, ya que actúa como documentación (sin necesidad de documentar la década de lista devuelta inmutabilidad en el Javadoc) y como un contrato de API. Es como decir "I garantía esta lista para ser inmutable, usted no tiene que preocuparse o defensiva copio". Y es muy concisa.
  • ImmutableList.copyOf() es grande, ya que rechaza automáticamente listas nulos (por tirar NullPointerException). También rechaza elementos nulos. Y no va a copiar la lista de origen si ya está un ImmutableList, lo que evita la instanciación de objetos inútiles.
  • En el segundo ejemplo, inicializar el campo a un ImmutableList vacío usando ImmutableList.of(), porque es una buena práctica para volver colecciones vacías en lugar de valores nulos ( Null modelo objeto ). Se podría pensar que esto crea instancias de objetos innecesarios, pero ImmutableList.of() realidad devuelve un producto único.

Hay una alternativa al método unmodifiableList. Usted sólo puede devolver una copia de esta matriz privada. Por ejemplo,

    return your_private_array.clone();

Bueno, podría haber una penalización en el rendimiento de este. Pero usted tiene interfaz sin cambios (aún devolver una matriz).

unmodifiableList es definitivamente la respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top