Re: Make Array Unmodifiable?

Discussion in 'Java' started by Roedy Green, May 31, 2004.

  1. Roedy Green

    Roedy Green Guest

    On 31 May 2004 05:50:40 -0700, (Ken) wrote or quoted
    :

    >Is there a standard approach or pattern for making an array that
    >cannot be modified? I ask this in this context: I'd like to be able
    >to return an array from a class method without letting the caller
    >subsequently modify the array.


    You don't give him the raw array. You give him an wrapper object with
    means to examine the elements but not set them.

    See http://mindprod.com/jgloss/immutable.html


    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, May 31, 2004
    #1
    1. Advertising

  2. Roedy Green

    Liz Guest

    "Roedy Green" <> wrote in message
    news:...
    > On 31 May 2004 05:50:40 -0700, (Ken) wrote or quoted
    > :
    >
    > >Is there a standard approach or pattern for making an array that
    > >cannot be modified? I ask this in this context: I'd like to be able
    > >to return an array from a class method without letting the caller
    > >subsequently modify the array.

    >
    > You don't give him the raw array. You give him an wrapper object with
    > means to examine the elements but not set them.


    Isn't this sort of like using get/set ? If a calling method does
    a get on your primitive data, like s/he gets the value for 'totalSales'
    you have no control over what s/he does with it as long as s/he
    doesn't damage your internal copy. Is it not the same with other data?
    Liz, May 31, 2004
    #2
    1. Advertising

  3. Roedy Green

    kk_oop Guest

    Liz gave me a follow up question.

    How do you preserve encapsulation with a get method? Does the "return"
    command return a reference to the internal attribute? Won't the caller
    be able then to use that reference to modify the value of the called
    classes attributes? Or should getter methods always be written to
    return a clone?

    Also, does "return" treat fundemental types (int, float, char, etc.)
    differently than user defined types (classes, arrays, collections)?

    Thanks again,

    Ken

    Liz wrote:

    >"Roedy Green" <> wrote in message
    >news:...
    >
    >
    >>On 31 May 2004 05:50:40 -0700, (Ken) wrote or quoted
    >>:
    >>
    >>
    >>
    >>>Is there a standard approach or pattern for making an array that
    >>>cannot be modified? I ask this in this context: I'd like to be able
    >>>to return an array from a class method without letting the caller
    >>>subsequently modify the array.
    >>>
    >>>

    >>You don't give him the raw array. You give him an wrapper object with
    >>means to examine the elements but not set them.
    >>
    >>

    >
    >Isn't this sort of like using get/set ? If a calling method does
    >a get on your primitive data, like s/he gets the value for 'totalSales'
    >you have no control over what s/he does with it as long as s/he
    >doesn't damage your internal copy. Is it not the same with other data?
    >
    >
    >
    >
    kk_oop, Jun 1, 2004
    #3
  4. Roedy Green

    Ryan Stewart Guest

    > "kk_oop<no spam> @yahoo.com>" <"kk_oop<no spam> wrote in
    > message news:40bbdb2e$0$3137$...
    > > Liz wrote:
    > > Isn't this sort of like using get/set ? If a calling method does
    > > a get on your primitive data, like s/he gets the value for 'totalSales'
    > > you have no control over what s/he does with it as long as s/he
    > > doesn't damage your internal copy. Is it not the same with other data?
    > >

    > Liz gave me a follow up question.
    >
    > How do you preserve encapsulation with a get method? Does the
    > "return" command return a reference to the internal attribute? Won't
    > the caller be able then to use that reference to modify the value of the
    > called classes attributes? Or should getter methods always be written
    > to return a clone?
    >
    > Also, does "return" treat fundemental types (int, float, char, etc.)
    > differently than user defined types (classes, arrays, collections)?


    Both of you seem confused on some Java basics. These questions are better
    posted to comp.lang.java.help. First, encapsulation (OO basic, not Java
    specific) refers to having a well defined public interface and hiding the
    details of internal implementation. Next, the types are "primitive" and
    "reference", not fundamental and user defined. In answer to your questions,
    when you return a reference type, you are returning a reference to an
    object. The caller can do anything to that object that the object allows. To
    your next question, an emphatic No! Getter methods should *not* always
    return a clone. That would be ridiculously inefficient. Finally, primitive
    types and reference types are treated exactly the same in assignment,
    parameter passing, returning, etc. You just have to realize that a reference
    is like a handle to an object. You don't pass the object itself, just a
    reference to it.
    Ryan Stewart, Jun 1, 2004
    #4
  5. Roedy Green

    kk_oop Guest

    My question remains. If a getter returns a reference to a class
    attribute, it would seem that the caller could take that reference and
    start changing the value of what it is referring to.

    Let me clarify with an example. Let's say I have a class x that has a
    private attribute mySize. I also have defined a public getter called
    getSize. I don't want anyone outside of an instance of x to alter
    mySize. x handles that internally (ie, mySize maintenance is
    encapsulated). This means I would never want a caller of getSize to be
    able to change an x object's internal value of mySize. The would be
    disasterous for the stability of the x object's state. This is why I
    say that the getter seems to break the encapsulation of mySize.

    So:

    1- Is my description accurate that the caller of myX.getSize( ) can take
    the returned reference and use it to change the value of the private
    mySize attribute?

    2- What is the standard java way of preventing this for both primitive
    and reference data types?

    Thanks,

    Ken

    Ryan Stewart wrote:

    >Both of you seem confused on some Java basics. These questions are better
    >posted to comp.lang.java.help. First, encapsulation (OO basic, not Java
    >specific) refers to having a well defined public interface and hiding the
    >details of internal implementation. Next, the types are "primitive" and
    >"reference", not fundamental and user defined. In answer to your questions,
    >when you return a reference type, you are returning a reference to an
    >object. The caller can do anything to that object that the object allows. To
    >your next question, an emphatic No! Getter methods should *not* always
    >return a clone. That would be ridiculously inefficient. Finally, primitive
    >types and reference types are treated exactly the same in assignment,
    >parameter passing, returning, etc. You just have to realize that a reference
    >is like a handle to an object. You don't pass the object itself, just a
    >reference to it.
    >
    >
    >
    >
    kk_oop, Jun 1, 2004
    #5
  6. "kk_oop<no spam>" <"kk_oop <no spam>"@yahoo.com> scribbled the following:
    > My question remains. If a getter returns a reference to a class
    > attribute, it would seem that the caller could take that reference and
    > start changing the value of what it is referring to.


    > Let me clarify with an example. Let's say I have a class x that has a
    > private attribute mySize. I also have defined a public getter called
    > getSize. I don't want anyone outside of an instance of x to alter
    > mySize. x handles that internally (ie, mySize maintenance is
    > encapsulated). This means I would never want a caller of getSize to be
    > able to change an x object's internal value of mySize. The would be
    > disasterous for the stability of the x object's state. This is why I
    > say that the getter seems to break the encapsulation of mySize.


    > So:


    > 1- Is my description accurate that the caller of myX.getSize( ) can take
    > the returned reference and use it to change the value of the private
    > mySize attribute?


    If the type of the private mySize attribute is a primitive, no way in
    heck is anyone going to alter its value if all they have is the return
    value from myX.getSize().
    If it's a reference type, it's slightly more complex. If the reference
    value is reassigned to refer to another object, the private mySize
    attribute is still safe, nothing has changed. But if the object itself
    is changed through the reference, then the changes are also visible in
    the private mySize attribute. It's the same object.

    > 2- What is the standard java way of preventing this for both primitive
    > and reference data types?


    For primitive types: It's already done for you. You'd have a more
    difficult time *allowing* this behaviour than preventing it.
    For reference types: Just make sure the returned object doesn't have
    any public methods or fields that would alter its internal state.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "A computer program does what you tell it to do, not what you want it to do."
    - Anon
    Joona I Palaste, Jun 1, 2004
    #6
  7. Roedy Green

    P.Hill Guest

    Joona I Palaste wrote:
    >Just make sure the returned object doesn't have
    > any public methods or fields that would alter its internal state.


    Hence, this is exactly why String objects are immutable.
    It wouldn't be so cool, if for example, the value inside a
    String used as a key in a hashtable was manipulated while it
    was still supposed to be the key value. It might, or should
    I say, mostly likely, result in very strange results.
    immutable objects thus are a very useful pattern in Java
    software and also why Java is so good at garbage collecting
    small young objects, since you can produce lots of them in
    very important and functionally useful situations.

    -Paul
    P.Hill, Jun 1, 2004
    #7
  8. Roedy Green

    Liz Guest

    "P.Hill" <> wrote in message
    news:c9iba0$pbq$...
    > Joona I Palaste wrote:
    > >Just make sure the returned object doesn't have
    > > any public methods or fields that would alter its internal state.

    >
    > Hence, this is exactly why String objects are immutable.
    > It wouldn't be so cool, if for example, the value inside a
    > String used as a key in a hashtable was manipulated while it
    > was still supposed to be the key value. It might, or should
    > I say, mostly likely, result in very strange results.
    > immutable objects thus are a very useful pattern in Java
    > software and also why Java is so good at garbage collecting
    > small young objects, since you can produce lots of them in
    > very important and functionally useful situations.
    >
    > -Paul
    >


    What sort of users do you have that are going to screw around
    with your hidden data? Didn't you make it clear that they can't do this?
    And if they do, they have no recourse to blame you for their misuse.
    Liz, Jun 1, 2004
    #8
  9. Roedy Green

    Liz Guest

    "Liz" <> wrote in message
    news:bE4vc.32103$eY2.7683@attbi_s02...
    >
    > "P.Hill" <> wrote in message
    > news:c9iba0$pbq$...
    > > Joona I Palaste wrote:
    > > >Just make sure the returned object doesn't have
    > > > any public methods or fields that would alter its internal state.

    > >
    > > Hence, this is exactly why String objects are immutable.
    > > It wouldn't be so cool, if for example, the value inside a
    > > String used as a key in a hashtable was manipulated while it
    > > was still supposed to be the key value. It might, or should
    > > I say, mostly likely, result in very strange results.
    > > immutable objects thus are a very useful pattern in Java
    > > software and also why Java is so good at garbage collecting
    > > small young objects, since you can produce lots of them in
    > > very important and functionally useful situations.
    > >
    > > -Paul
    > >

    >
    > What sort of users do you have that are going to screw around
    > with your hidden data? Didn't you make it clear that they can't do this?
    > And if they do, they have no recourse to blame you for their misuse.
    >

    Maybe you should just call System.exit() if they change it.
    Liz, Jun 1, 2004
    #9
  10. Roedy Green

    Ken Guest

    Joona I Palaste <> wrote in message news:<c9huov$5ms$>...
    > "kk_oop<no spam>" <"kk_oop <no spam>"@yahoo.com> scribbled the following:


    > For reference types: Just make sure the returned object doesn't have
    > any public methods or fields that would alter its internal state.


    So would a typical approach be to define an interface for the class
    that contained only the readonly methods, then use this as the return
    type for the getter? This way I'd be returning the encapsulated
    instance, but the client would only be able to access it via the
    readonly interface. So it would be something like this:

    public interface Class1ReadOnlyInterface
    {
    public int getThis();
    public float getThat();
    }

    public class Class1 implements Class1ReadOnlyInterface
    {
    public int getThis()
    { ....... }

    public float getThat()
    { ....... }

    public void changeThis(int x)
    { ....... }

    public void changeThat(float x)
    { ....... }

    private int mthis;
    private float mthat;

    }

    public class Class2
    {
    public Class1ReadOnlyInterface getClass1()
    {
    return theClass1;
    }
    ...

    private Class1 theClass1;
    ...
    }

    Is that right, or is there a simpler standard approach? I'm not
    looking to reinvent the wheel here. I just figure this must not be an
    unusual situation, so I'm just looking for an "accepted" way of
    handling it.


    Thanks again,

    Ken
    Ken, Jun 1, 2004
    #10
  11. Roedy Green

    P.Hill Guest

    Liz wrote:

    > "Liz" <> wrote in message
    >>What sort of users do you have that are going to screw around
    >>with your hidden data? Didn't you make it clear that they can't do this?
    >>And if they do, they have no recourse to blame you for their misuse.
    >>

    >
    > Maybe you should just call System.exit() if they change it.


    It may be the case that the data isn't hidden. In fact this wouldn't be a
    problem unless there was some contract to provide values to the caller. Some
    APIs provide access to keys and their values in various collections with String
    immutable the provider of the library doesn't have to worry when it returns a
    reference to a key that someone might screw up and change it.

    BTW, if a library returned a mutable String and the library really wanted to
    blow up and exit() when a caller did the wrong thing and mis-coded the app by
    accidentally changing a key value, the guarding code would have to be programmed
    into the object stored in the key. Since we've already assumed that getting a
    key value (for comparison maybe) is a legal operation, then once the caller has
    a reference to the key object, they would call on the key object directly.
    Since this obviously means a special key object, it is more general for the Sun
    designers to provide an immutable special object that is useful in this type of
    situation, preventing any updates. Hence the general need for an immutable (no
    setters) String, Integer etc.

    Am I making any sense?
    -Paul
    P.Hill, Jun 1, 2004
    #11
  12. Roedy Green

    Ryan Stewart Guest

    "Ken" <> wrote in message
    news:...
    > Joona I Palaste <> wrote in message

    news:<c9huov$5ms$>...
    > > "kk_oop<no spam>" <"kk_oop <no spam>"@yahoo.com> scribbled the

    following:
    > So would a typical approach be to define an interface for the class
    > that contained only the readonly methods, then use this as the return
    > type for the getter? This way I'd be returning the encapsulated
    > instance, but the client would only be able to access it via the
    > readonly interface.
    >

    Of course not. All the user has to do is cast it.

    > Is that right, or is there a simpler standard approach? I'm not
    > looking to reinvent the wheel here. I just figure this must not be an
    > unusual situation, so I'm just looking for an "accepted" way of
    > handling it.
    >

    Design your objects to be mutable or immutable as needed.
    Ryan Stewart, Jun 2, 2004
    #12
  13. Roedy Green

    kk_oop Guest

    See responses to Ryan below.

    Ryan Stewart wrote:

    >>
    >>
    >>

    >Of course not. All the user has to do is cast it.
    >

    Agreed. But I figured the idea was to let the client know that he
    shouldn't change the class. I was thinking that if the returning
    interface does not include the setter methods, the client would get the
    idea that setters should not be used. He can still cast, but at that
    point, I'd think he was intentionally trying to break the encapsulation.

    >Design your objects to be mutable or immutable as needed.
    >

    If the approach I mentioned above is not the way to go, how would you
    recommend making the contained object mutable to the class that contains
    it but immutable to everyone else?

    Once again, thanks for the input!

    Ken
    kk_oop, Jun 2, 2004
    #13
  14. Roedy Green

    kk_oop Guest

    Liz wrote:

    >>
    >>
    >>

    >
    >What sort of users do you have that are going to screw around
    >with your hidden data? Didn't you make it clear that they can't do this?
    >And if they do, they have no recourse to blame you for their misuse.
    >

    I think the assumption is that users would unknowingly screw around with
    hidden data at some point if they were allowed to. That's the whole
    reason to have protected and private scope. It just seems that
    returning a reference to these private or protected objects defeats the
    purpose of making them private or protected to begin with.

    - Ken
    kk_oop, Jun 2, 2004
    #14
  15. Roedy Green

    kk_oop Guest

    Where can I find a description of the immutable pattern? Is there one
    online somewhere? That sounds like its exactly what I'm looking for.

    Thanks!

    Ken

    P.Hill wrote:

    >
    > Hence, this is exactly why String objects are immutable.
    > It wouldn't be so cool, if for example, the value inside a
    > String used as a key in a hashtable was manipulated while it
    > was still supposed to be the key value. It might, or should
    > I say, mostly likely, result in very strange results.
    > immutable objects thus are a very useful pattern in Java
    > software and also why Java is so good at garbage collecting
    > small young objects, since you can produce lots of them in
    > very important and functionally useful situations.
    >
    > -Paul
    >
    kk_oop, Jun 2, 2004
    #15
  16. Roedy Green

    Roedy Green Guest

    On Tue, 01 Jun 2004 21:24:13 -0400, "kk_oop<no spam>" <"kk_oop<no
    spam>"@yahoo.com> wrote or quoted :

    >Where can I find a description of the immutable pattern? Is there one
    >online somewhere? That sounds like its exactly what I'm looking for.


    see http://mindprod.com/jgloss/immutable.html

    It is not grand enough to be called a design pattern.

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, Jun 2, 2004
    #16
  17. Roedy Green

    Chris Smith Guest

    "kk_oop<no spam>" <"kk_oop<no spam>"@yahoo.com> wrote:
    > I think the assumption is that users would unknowingly screw around with
    > hidden data at some point if they were allowed to. That's the whole
    > reason to have protected and private scope. It just seems that
    > returning a reference to these private or protected objects defeats the
    > purpose of making them private or protected to begin with.


    Ken,

    Pardon for jumping in, but I think there's still confusion because
    you're confusing objects with variables. In a lot of situations, people
    (including me) speak casually as if these were the same thing; but in
    situations like this one there's a need to be more precise.

    Specifically, there's no such thing as a private or protected object.
    Only variables can be private or protected. It's then impossible to
    return a reference to a variable, because there is no such thing;
    references only point to objects, not variables.

    The private or protected modifier, then, prevent the wrong person from
    reading or modifying the variable... but yes, it's possible to write a
    method that returns a copy of the variable. If that variable points to
    an object(i.e., it's a reference variable rather than a primitive, and
    it's not null), then the resulting copy also points to the object; and
    at that point you still can't do anything to the private or protected
    variable, but you might be able to do something to the object it points
    to -- depending on what public methods exist in the object.

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Jun 2, 2004
    #17
  18. Roedy Green

    Liz Guest

    "kk_oop<no spam> @yahoo.com>" <"kk_oop<no spam> wrote in message
    news:40bd2807$0$2974$...
    See responses to Ryan below.

    Ryan Stewart wrote:



    Of course not. All the user has to do is cast it.
    Agreed. But I figured the idea was to let the client know that he shouldn't
    change the class. I was thinking that if the returning interface does not
    include the setter methods, the client would get the idea that setters
    should not be used. He can still cast, but at that point, I'd think he was
    intentionally trying to break the encapsulation.

    Design your objects to be mutable or immutable as needed.
    If the approach I mentioned above is not the way to go, how would you
    recommend making the contained object mutable to the class that contains it
    but immutable to everyone else?

    Once again, thanks for the input!

    Ken

    ------------
    How about changing the interface such that the calling method
    provides a reference to their own array and you copy yours into his?
    Liz, Jun 2, 2004
    #18
  19. Ryan Stewart wrote:

    > Of course not. All the user has to do is cast it.


    Of course not. Users can't cast anything, only programmers. And if
    somebody is getting your system to execute his code, he can do
    *anything* he likes anyway.

    protected and private aren't about *preventing* people to screw
    with your code, they're about giving them hints about how your code
    should and should not be used in order to run correctly.
    Michael Borgwardt, Jun 2, 2004
    #19
  20. Roedy Green

    kk_oop Guest

    Liz wrote:

    >------------
    >How about changing the interface such that the calling method
    >provides a reference to their own array and you copy yours into his?
    >
    >
    >

    Hi Liz.

    I'm concerned about doing a deep copy of an array, as that can mean a
    significant performance hit if that array gets pretty big. So I think
    the suggestions I've heard that seem to make the most sense for my
    situation are one of the following:

    1- Make a read only interface for the class and return a reference to
    that interface instead of returning the actual object's interface.
    2- Make a readonly wrapper around the reference that will only provide
    delegation to the readonly portion of the class.

    I really appreciate yours and everyone else's input! I'm coming from a
    C++ world and am trying to see what the standard Java approach is to
    problems like this. This use group is quite helpful!

    See ya,

    Ken
    kk_oop, Jun 2, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rune Berge

    Re: Make Array Unmodifiable?

    Rune Berge, May 31, 2004, in forum: Java
    Replies:
    1
    Views:
    407
    Roedy Green
    May 31, 2004
  2. P.Hill

    Re: Make Array Unmodifiable?

    P.Hill, May 31, 2004, in forum: Java
    Replies:
    1
    Views:
    3,599
    Andrew Thompson
    May 31, 2004
  3. Laax
    Replies:
    2
    Views:
    434
  4. Ian Pilcher

    Unmodifiable ResultSet wrapper?

    Ian Pilcher, Aug 29, 2011, in forum: Java
    Replies:
    3
    Views:
    694
  5. LAMBEAU Bernard
    Replies:
    1
    Views:
    85
    Markus Schirp
    Jan 8, 2009
Loading...

Share This Page