• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

modifying through getters?

 
glup klosar
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Suppose you write a class with private fields for which you provide getter methods. Is it possible for the fields to be modified through them, and if so, you do you stop this?
(sth like the const keyword in C++ in the method signature)
 
Vivek Kr Singh
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes it's possible to modify private fields when using getters. Look at this example below in which an element is being added to list retrieved from getter


Now look at this another example in which getter is not letting reference to actual object escape. It is returning a view of underlaying collection.Only the getField operation has changed

If you don't want fields to be modified using getter then
  • Use Immutable Classes
  • Provide a view of the undelaying fields
  • Create new objects and use a copy constructor to copy values to new Object
  •  
    Jesper de Jong
    Java Cowboy
    Saloon Keeper
    Pie
    Posts: 15369
    40
    Android IntelliJ IDE Java Scala Spring
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    In Java, there is nothing like const in C++. So you cannot use const in Java to prevent getter methods from modifying the state of the object - you'll just have to trust the developer not to do so.

    There is the keyword final in Java, but it does not do the same as const in C++.

    See Const-correctness in Wikipedia:
    There is no way to declare that you will not modify the object pointed to by a reference through that reference in Java. Thus there are also no const methods. Const-correctness cannot be enforced in Java, although by use of interfaces and defining a read-only interface to your class and passing this around, you have a means to ensure that you can pass your objects around the system in a way they cannot be modified.

    Methods in Java can be declared "final", but that has a completely unrelated meaning - it means that the method cannot be overridden in subclasses.

    Interestingly, the Java language specification regards const as a reserved keyword — i.e., one that cannot be used as variable identifier — but assigns no semantics to it. It is thought that the reservation of the keyword occurred to allow for an extension of the Java language to include C++-style const methods and pointer to const type. The enhancement request ticket in the Java Community Process for implementing const correctness in Java was closed in 2005, implying that const correctness will probably never find its way into the official Java specification.
     
    Campbell Ritchie
    Sheriff
    Pie
    Posts: 49472
    64
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Please avoid abbreviations like "sth" for reasons explained here.

    The way to prevent private reference instance fields from being modified is to return a copy of the field. In the case of the method with a List return type above, try this method insteadNote the returned List will reflect any changes made in the original class.
    For other mutable objects, a copy of the original field is useful; such classes should provide a copy constructor or implement a clone() method.
    For things like String which are not mutable, or for primitives, there is no need for any special precautions.
     
    glup klosar
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    OK, so if it is a collection, I will use Collection.umodifiable. However, if it is a primitive, or an object, I have to supply a copy(it is the only way) right?
     
    David O'Meara
    Rancher
    Posts: 13459
    Android Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Close but not quite.

    Anything that cannot be modified can be returned directly. This includes primitives and immutable types (eg String)
    Anything that can be modified should have either an immutable or defensive copy returned

    Therefore:
    int is a primitive, so return the int;
    Integer is immutable, so return the Integer
    Collections are mutable so return immutable copies
    Dates are mutable, so return defensive copies eg return new Date(oldDate)
     
    glup klosar
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hmmm...so if field is an int, in the getter I say return Integer(field);
    in that case, even if userstry to modify the obtained integer, because of immutability, that will result in creating new Integer, and field will remain unchanged?
     
    Vijitha Kumara
    Bartender
    Posts: 3913
    9
    Chrome Fedora Hibernate
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    glup klosar wrote:Hmmm...so if field is an int, in the getter I say return Integer(field);

    That's not neccessary. "int" is primitive(not object) so only the value is passed.
     
    glup klosar
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    so how would that line look like? (return...)
     
    Vijitha Kumara
    Bartender
    Posts: 3913
    9
    Chrome Fedora Hibernate
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    glup klosar wrote:so how would that line look like? (return...)


    Here the caller gets it's own copy.
     
    David O'Meara
    Rancher
    Posts: 13459
    Android Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Or testing using a variant of your original code:


    Question: did we manage to change the internal value?
    (Note that people will always chime in and say that it is possible using reflection. While this is worth considering it is related it is more of a security topic than a beginner topic)
     
    glup klosar
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    OK, I get it. So, I only need to care when dealing with mutables, and in that case I provide a defensive copy in the getter, or if it is a collections I use .unmodifiable.
     
    Jesper de Jong
    Java Cowboy
    Saloon Keeper
    Pie
    Posts: 15369
    40
    Android IntelliJ IDE Java Scala Spring
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes, and for primitive types (byte, short, int, long, char, float, double, boolean) you never need to make defensive copies, because they are direct values (and not references to possibly mutable objects).
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic