0

Having the get set model:

public class exampleclass
{
    private Something something;

    public Something getSomething()
    {
        return something;
    }

    public void setSomething(Something st)
    {
         something = st;
    }
}

I wanna make something like this:

public class exampleclass
{
    public Something something;

    public void setSomething(Something st)
    {
         something = st;
    }
}

But i want to have "something" var with readOnly feature out of the class (but rewritable in the own class). Any idea of how to do this for an optimized access. (Think this is gonna be used in android , but using a pure java only framework (libgdx) )

A.Quiroga
  • 5,704
  • 6
  • 37
  • 58
  • What do you mean saying *optimized*? Such calls will be JITted, even on dalvik (well, on recent versions of dalvik). – om-nom-nom Dec 16 '12 at 15:21
  • do you mean get() calls are already optimized? – A.Quiroga Dec 16 '12 at 15:25
  • Yes, [since Gingerbread](http://stackoverflow.com/a/4930538/298389). And it's definitely can be optimized by Hotspot. – om-nom-nom Dec 16 '12 at 15:31
  • but one of the thing android says is : Avoid using get set functions to not overload calling more encapsulated functions. – A.Quiroga Dec 16 '12 at 15:33
  • No get() calls are not always optimized! For that reason java.awt.Point have direct access to x, and y (point.x, point.y) because in graphics high performance is needed. – AlexWien Dec 16 '12 at 15:34
  • 1
    @AlexWien are we talking about [JIT](http://en.wikipedia.org/wiki/Just-in-time_compilation) optimization? ;-) JIT doesn't optimize **any** calls, but frequent ones. BTW, can you provide a reference to the statement, that direct access to java.awt.Point was designed in such way, to eliminate function call overhead? – om-nom-nom Dec 16 '12 at 15:37
  • JIT compiles. sometimes it can inline getter, but not always. – AlexWien Dec 16 '12 at 15:43
  • @AlexWien I've [provided](http://stackoverflow.com/questions/13902682/is-there-any-way-to-have-readonly-feature-without-using-get-in-get-set-mod/13902714#comment19157814_13902682) a link on the words of Google engineer (from Android JIT team) which says that *this particular getter* (e.g. just field read, no conditionals) will be JITted. Sorry, if I confused you and made thinking that I'm stating that any call can be optimized. – om-nom-nom Dec 16 '12 at 15:49
  • Thanks for the link, i will read it later. JITed does not mean inlined (Or does it?) . JIT could compile the get method, having one indirection, still in assembler – AlexWien Dec 16 '12 at 15:55
  • @AlexWien, yes, it does mean inlining (the link is in 3rd comment, btw). – om-nom-nom Dec 16 '12 at 15:57
  • I dont think so, that depens on the getter, if it is a huge getter with 2000 lines of code it will not be inlined. See c compiler. all is compiled, but not all is inlined. A standard getter may be inlined – AlexWien Dec 16 '12 at 16:11
  • 1
    @AlexWien the public access to the coordinates of `java.awt.Point` is generally [considered a mistake](http://books.google.com/books?id=Ft8t0S4VjmwC&pg=PA80&lpg=PA80&dq=effective+java+awt+point&source=bl&ots=D3ya-8tEAl&sig=0Pxn00mya2BwC1UbJLbkriXheuc&hl=en&sa=X&ei=GwLOUPS9Lef_igLvsIEI&ved=0CGAQ6AEwBQ#v=onepage&q=effective%20java%20awt%20point&f=false) by the authors of Java that can't be corrected now. – Louis Wasserman Dec 16 '12 at 17:17
  • @LouisWasserman Josh Bloch is one of the java authors, he did not implement class Point. i remember that the author of Point or somebody else at Sun, stated that they had a perfomance problem when x and y would not be directly accessible. further it is horrible using getters in geometric formulas. – AlexWien Dec 16 '12 at 21:43

3 Answers3

3

You can set thoose things in constructor and expose public final field:

public class ExampleClass
{
    public final Something something;

    public ExampleClass(Something st)
    {
         something = st;
    }
}
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
0

You could use the final keyword. The you can assign it once.

e.g

public class Exampleclass
{
    public final Something something;
    void Exampleclass(Something init) {
        this.something = init;
    }
}

However the content of Something still could be changed, so you may consider returning a clone() of something. (see the class java.util.Date, you still could set the timestamp, in such cases only clone() or a copy constructor helps) . But if your code is not a public lib, then you can leav that getter with clone() away

public class Exampleclass
    {
        private Something something;
        void Exampleclass(Something init) {
            this.something = init;
        }
       void Something getSomething() {
            return something.clone();
        }

    }

But that depends on Something. Another soultion is a Factory Pattern, such that only the Factory can create Something. Then there is no public constructor in Something. Only the factory can create it.

public class Something() {
   private int value;
   protectectd Something(int value) {
      this.value = value;
   }
   public tostring() {
      System.out.println("values = " + value);
   }
}
public class SomethingFactory() {
  protected static Someting createSomething(int value)  {
     return new Something(value);   
 }
}

USage:

Something some = SomethingFactory.createSomething(3);

But read more by search "java Deisgn Patterns Factory" or FactoryPattern

AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • but what i want is optimized access also . cloning isnt optimized and have nonsense since what i want is not need of get() call but directly using the var – A.Quiroga Dec 16 '12 at 15:26
  • then use the final approach and make something protected or public – AlexWien Dec 16 '12 at 15:27
  • but final approach can't set more than once the var – A.Quiroga Dec 16 '12 at 15:30
  • final, yes once, you wanted it read only! Otherwise you coul duse A factory pattern, such that only the factory can construct Something. and the factro is protected in that package. – AlexWien Dec 16 '12 at 15:38
  • that's the question , if i put direct access to Something , the var will be writable (which is what i dont want) . – A.Quiroga Dec 16 '12 at 15:38
0

I guess your issue is escaping reference, if you want to save your object while returning, send a copy of reference, you can send cloned object using clone method.

public Something getSomething()
{
    return something.clone();
}

This will return object shallow copy, if you want make deep cloning override the clone() method Hope this will help..

Eric Aya
  • 69,473
  • 35
  • 181
  • 253