2010-03-12 15 views
10

En mi aplicación Java que tienen una cierta copia-constructores como estaAcceso de campo privado de otro objeto en constructores de copia - ¿Realmente es un problema?

public MyClass(MyClass src) { 
    this.field1 = src.field1; 
    this.field2 = src.field2; 
    this.field3 = src.field3; 
... 
} 

ahora Netbeans 6.9 advierte sobre esto y me pregunto lo que está mal con este código?

Mis preocupaciones:

  • Uso de los captadores pueden introducir efectos secundarios no deseados. Es posible que el nuevo objeto ya no se considere una copia del original.
  • Si se recomienda el uso de getters, ¿no sería más consistente si se usaran setters para la nueva instancia también?

EDIT: La advertencia es real "Acceso del ámbito privado de otro objeto" y la única acción disponible Netbeans ofrece es la adición de un @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")

Mi código es realmente tan trivial como el ejemplo dado.

+0

¿Cuál es la advertencia de Netbeans? – Timothy

+0

Actualicé mi pregunta –

+1

Solo puedo especular sobre el motivo: Algunas personas piensan que 'privado' significa que solo el * objeto * actual puede acceder al campo (mientras que en realidad otros objetos de la misma clase también pueden acceder al campo). Tal vez esta advertencia sea un recordatorio de que esto es realmente posible y para evitar que las personas lo hagan accidentalmente. –

Respuesta

7

No veo ningún problema con el código. De hecho, comparto sus preocupaciones y preferiría no utilizar getters.

¿Cuál es exactamente la advertencia que recibe? ¿Tal vez está relacionado con algo que no nos estás mostrando?

Actualización: Parece Netbeans es realmente quejaba de eso. Esa es una advertencia bastante controvertida para enviar con un IDE, creo.

+4

Absolutamente. El concepto de privado es * privado para la implementación de clase *, en mi opinión. Un constructor de copia es parte de la implementación de clase y puede hacer lo que quiera con datos privados. –

+0

Dicha copia es un problema si los campos no son primitivos, pero los campos de los cuales el contenido puede cambiar. Aunque así lo desee, puede obtener problemas de simultaneidad. – extraneon

+0

@extraneon: Parece estar fuera del alcance de la advertencia. Envolver cosas en getters tampoco va a hacer la diferencia allí. – Thilo

0

Tal vez la clase podría proporcionar un método de copia superficial que sepa qué datos devolver en un objeto copiado. Si es necesario, puede proporcionar una copia profunda también.

public MyClass shallowCopy() { 
    MyClass aCopy = new MyClass(); 
    aCopy.field1 = this.field1; 
    aCopy.field2 = this.field2; 
    aCopy.field3 = this.field3; 
} 
+0

Esto da exactamente la misma advertencia. –

4

No sé por qué NetBeans advierte, pero efectivamente está haciendo una copia superficial. Su copia comparte field1, field2 y field3 con src y, como tal, una modificación de field3, por ejemplo, una lista, se reflejará en el original.

private List field1; 

public MyClass(MyClass src) { 
    this.field1 = src.field1; 
    this.field2 = src.field2; 
    this.field3 = src.field3; 

    field1.add(new Object()); // field1 of src also modified 
... 
} 
+0

Buen punto, no pensé en tipos mutables. Pero en este caso solo estoy copiando los tipos 'int' y' String' –

6

Me recuerda a la discusión ADT vs objeto.

ADT puede acceder al estado interno de otra instancia del ADT. La filosofía del objeto evitaría eso e impondría el acceso a través de getter/setter para garantizar independencia de representación.

Ha sido una elección deliberada que instancias de variables en Java son clase privada, no -objeto privado (En este último caso sólo se this.privateInstVar está permitido, no obj.privateInstVar).

Esto tiene tanto puntos fuertes como débiles. Es especialmente práctico cuando se trata de clonando y igualdad. Por otro lado, puede ser mal utilizado y romper encapsulación.

Es casi un debate filosófico. Pero en mi humilde opinión, lo que estás haciendo está bien.

Cuestiones relacionadas